blob: 58678a0acb294fa176ebfafd6219e22ca5ca9b18 [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{
TDYa12755e5e6c2012-09-11 15:14:42 -0700173 QuickCompiler* quick = cUnit->quick_compiler;
buzbee692be802012-08-29 15:52:59 -0700174 cUnit->context = quick->GetLLVMContext();
175 cUnit->module = quick->GetLLVMModule();
176 cUnit->intrinsic_helper = quick->GetIntrinsicHelper();
177 cUnit->irb = quick->GetIRBuilder();
buzbee2cfc6392012-05-07 14:51:40 -0700178}
179
180const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
181 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
182}
183
buzbeef58c12c2012-07-03 15:06:29 -0700184llvm::BasicBlock* findCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
185{
186 BasicBlock* bb = oatFindBlock(cUnit, vaddr);
187 DCHECK(bb != NULL);
188 return getLLVMBlock(cUnit, bb->id);
189}
190
191void convertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
192 int32_t tableOffset, RegLocation rlSrc)
193{
194 const Instruction::PackedSwitchPayload* payload =
195 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
196 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
197
198 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
199
200 llvm::SwitchInst* sw =
201 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
202 payload->case_count);
203
204 for (uint16_t i = 0; i < payload->case_count; ++i) {
205 llvm::BasicBlock* llvmBB =
206 findCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
207 sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
208 }
209 llvm::MDNode* switchNode =
210 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
211 sw->setMetadata("SwitchTable", switchNode);
212 bb->taken = NULL;
213 bb->fallThrough = NULL;
214}
215
buzbeea1da8a52012-07-09 14:00:21 -0700216void convertSparseSwitch(CompilationUnit* cUnit, BasicBlock* bb,
217 int32_t tableOffset, RegLocation rlSrc)
218{
219 const Instruction::SparseSwitchPayload* payload =
220 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
221 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
222
223 const int32_t* keys = payload->GetKeys();
224 const int32_t* targets = payload->GetTargets();
225
226 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
227
228 llvm::SwitchInst* sw =
229 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
230 payload->case_count);
231
232 for (size_t i = 0; i < payload->case_count; ++i) {
233 llvm::BasicBlock* llvmBB =
234 findCaseTarget(cUnit, cUnit->currentDalvikOffset + targets[i]);
235 sw->addCase(cUnit->irb->getInt32(keys[i]), llvmBB);
236 }
237 llvm::MDNode* switchNode =
238 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
239 sw->setMetadata("SwitchTable", switchNode);
240 bb->taken = NULL;
241 bb->fallThrough = NULL;
242}
243
buzbee8fa0fda2012-06-27 15:44:52 -0700244void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
245 greenland::IntrinsicHelper::IntrinsicId id,
246 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700247{
buzbee8fa0fda2012-06-27 15:44:52 -0700248 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700249 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700250 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
251 defineValue(cUnit, res, rlDest.origSReg);
252}
253
254void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
255 greenland::IntrinsicHelper::IntrinsicId id,
256 RegLocation rlSrc)
257{
258 llvm::SmallVector<llvm::Value*, 2> args;
259 args.push_back(cUnit->irb->getInt32(fieldIndex));
260 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
261 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
262 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700263}
264
buzbee101305f2012-06-28 18:00:56 -0700265void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
266 RegLocation rlArray)
267{
268 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700269 id = greenland::IntrinsicHelper::HLFillArrayData;
buzbee101305f2012-06-28 18:00:56 -0700270 llvm::SmallVector<llvm::Value*, 2> args;
271 args.push_back(cUnit->irb->getInt32(offset));
272 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
273 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
274 cUnit->irb->CreateCall(intr, args);
275}
276
buzbee2cfc6392012-05-07 14:51:40 -0700277llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
278 RegLocation loc)
279{
280 greenland::IntrinsicHelper::IntrinsicId id;
281 if (loc.wide) {
282 if (loc.fp) {
283 id = greenland::IntrinsicHelper::ConstDouble;
284 } else {
285 id = greenland::IntrinsicHelper::ConstLong;
286 }
287 } else {
288 if (loc.fp) {
289 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700290 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700291 id = greenland::IntrinsicHelper::ConstObj;
292 } else {
293 id = greenland::IntrinsicHelper::ConstInt;
294 }
295 }
296 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
297 return cUnit->irb->CreateCall(intr, src);
298}
buzbeeb03f4872012-06-11 15:22:11 -0700299
300void emitPopShadowFrame(CompilationUnit* cUnit)
301{
302 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
303 greenland::IntrinsicHelper::PopShadowFrame);
304 cUnit->irb->CreateCall(intr);
305}
306
buzbee2cfc6392012-05-07 14:51:40 -0700307llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
308 RegLocation loc)
309{
310 greenland::IntrinsicHelper::IntrinsicId id;
311 if (loc.wide) {
312 if (loc.fp) {
313 id = greenland::IntrinsicHelper::CopyDouble;
314 } else {
315 id = greenland::IntrinsicHelper::CopyLong;
316 }
317 } else {
318 if (loc.fp) {
319 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700320 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700321 id = greenland::IntrinsicHelper::CopyObj;
322 } else {
323 id = greenland::IntrinsicHelper::CopyInt;
324 }
325 }
326 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
327 return cUnit->irb->CreateCall(intr, src);
328}
329
buzbee32412962012-06-26 16:27:56 -0700330void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
331{
332 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
333 greenland::IntrinsicHelper::GetException);
334 llvm::Value* res = cUnit->irb->CreateCall(func);
335 defineValue(cUnit, res, rlDest.origSReg);
336}
337
338void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
339{
340 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
341 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
TDYa127f71bf5a2012-07-29 20:09:52 -0700342 greenland::IntrinsicHelper::HLThrowException);
buzbee32412962012-06-26 16:27:56 -0700343 cUnit->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700344}
345
buzbee8fa0fda2012-06-27 15:44:52 -0700346void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
347 greenland::IntrinsicHelper::IntrinsicId id,
348 RegLocation rlSrc)
349{
350 llvm::SmallVector<llvm::Value*, 2> args;
351 args.push_back(cUnit->irb->getInt32(optFlags));
352 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
353 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
354 cUnit->irb->CreateCall(func, args);
355}
356
buzbee76592632012-06-29 15:18:35 -0700357void convertArrayLength(CompilationUnit* cUnit, int optFlags,
358 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700359{
360 llvm::SmallVector<llvm::Value*, 2> args;
361 args.push_back(cUnit->irb->getInt32(optFlags));
362 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
363 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700364 greenland::IntrinsicHelper::OptArrayLength);
buzbee76592632012-06-29 15:18:35 -0700365 llvm::Value* res = cUnit->irb->CreateCall(func, args);
366 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700367}
368
buzbee2cfc6392012-05-07 14:51:40 -0700369void emitSuspendCheck(CompilationUnit* cUnit)
370{
371 greenland::IntrinsicHelper::IntrinsicId id =
372 greenland::IntrinsicHelper::CheckSuspend;
373 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
374 cUnit->irb->CreateCall(intr);
375}
376
377llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
378 llvm::Value* src1, llvm::Value* src2)
379{
380 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700381 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700382 switch(cc) {
383 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
384 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
385 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
386 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
387 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
388 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
389 default: LOG(FATAL) << "Unexpected cc value " << cc;
390 }
391 return res;
392}
393
394void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
395 ConditionCode cc, RegLocation rlSrc1,
396 RegLocation rlSrc2)
397{
398 if (bb->taken->startOffset <= mir->offset) {
399 emitSuspendCheck(cUnit);
400 }
401 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
402 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
403 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
404 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
405 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
406 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700407 // Don't redo the fallthrough branch in the BB driver
408 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700409}
410
411void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
412 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
413{
414 if (bb->taken->startOffset <= mir->offset) {
415 emitSuspendCheck(cUnit);
416 }
417 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
418 llvm::Value* src2;
419 if (rlSrc1.ref) {
420 src2 = cUnit->irb->GetJNull();
421 } else {
422 src2 = cUnit->irb->getInt32(0);
423 }
424 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700425 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
426 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700427 // Don't redo the fallthrough branch in the BB driver
428 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700429}
430
431llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
432 llvm::Value* src1, llvm::Value* src2)
433{
434 greenland::IntrinsicHelper::IntrinsicId id;
435 if (isLong) {
436 if (isDiv) {
437 id = greenland::IntrinsicHelper::DivLong;
438 } else {
439 id = greenland::IntrinsicHelper::RemLong;
440 }
Logan Chien554e6072012-07-23 20:00:01 -0700441 } else {
442 if (isDiv) {
buzbee2cfc6392012-05-07 14:51:40 -0700443 id = greenland::IntrinsicHelper::DivInt;
444 } else {
445 id = greenland::IntrinsicHelper::RemInt;
Logan Chien554e6072012-07-23 20:00:01 -0700446 }
buzbee2cfc6392012-05-07 14:51:40 -0700447 }
448 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
449 llvm::SmallVector<llvm::Value*, 2>args;
450 args.push_back(src1);
451 args.push_back(src2);
452 return cUnit->irb->CreateCall(intr, args);
453}
454
455llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
456 llvm::Value* src1, llvm::Value* src2)
457{
458 llvm::Value* res = NULL;
459 switch(op) {
460 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
461 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700462 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700463 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
464 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
465 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
466 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
467 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
468 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700469 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
470 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
471 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700472 default:
473 LOG(FATAL) << "Invalid op " << op;
474 }
475 return res;
476}
477
478void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
479 RegLocation rlSrc1, RegLocation rlSrc2)
480{
481 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
482 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
483 llvm::Value* res = NULL;
484 switch(op) {
485 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
486 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
487 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
488 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
489 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
490 default:
491 LOG(FATAL) << "Invalid op " << op;
492 }
493 defineValue(cUnit, res, rlDest.origSReg);
494}
495
buzbee2a83e8f2012-07-13 16:42:30 -0700496void convertShift(CompilationUnit* cUnit,
497 greenland::IntrinsicHelper::IntrinsicId id,
498 RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
buzbee4f1181f2012-06-22 13:52:12 -0700499{
buzbee2a83e8f2012-07-13 16:42:30 -0700500 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
501 llvm::SmallVector<llvm::Value*, 2>args;
502 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
503 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
504 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
505 defineValue(cUnit, res, rlDest.origSReg);
506}
507
508void convertShiftLit(CompilationUnit* cUnit,
509 greenland::IntrinsicHelper::IntrinsicId id,
510 RegLocation rlDest, RegLocation rlSrc, int shiftAmount)
511{
512 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
513 llvm::SmallVector<llvm::Value*, 2>args;
514 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
515 args.push_back(cUnit->irb->getInt32(shiftAmount));
516 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700517 defineValue(cUnit, res, rlDest.origSReg);
518}
519
buzbee2cfc6392012-05-07 14:51:40 -0700520void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
521 RegLocation rlSrc1, RegLocation rlSrc2)
522{
523 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
524 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700525 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700526 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
527 defineValue(cUnit, res, rlDest.origSReg);
528}
529
buzbeeb03f4872012-06-11 15:22:11 -0700530void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
531{
532 int index = -1;
533 DCHECK(newVal != NULL);
534 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
535 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
536 if (cUnit->shadowMap[i] == vReg) {
537 index = i;
538 break;
539 }
540 }
TDYa127347166a2012-08-23 12:23:44 -0700541 if (index == -1) {
542 return;
543 }
buzbee6459e7c2012-10-02 14:42:41 -0700544 llvm::Type* ty = newVal->getType();
buzbeeb03f4872012-06-11 15:22:11 -0700545 greenland::IntrinsicHelper::IntrinsicId id =
546 greenland::IntrinsicHelper::SetShadowFrameEntry;
547 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
548 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
buzbee6459e7c2012-10-02 14:42:41 -0700549 // If newVal is a Null pointer, we'll see it here as a const int. Replace
550 if (!ty->isPointerTy()) {
551 // TODO: assert newVal created w/ dex_lang_const_int(0) or dex_lang_const_float(0)
552 newVal = cUnit->irb->GetJNull();
553 }
buzbeeb03f4872012-06-11 15:22:11 -0700554 llvm::Value* args[] = { newVal, tableSlot };
555 cUnit->irb->CreateCall(func, args);
556}
557
buzbee2cfc6392012-05-07 14:51:40 -0700558void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
559 RegLocation rlSrc1, int32_t imm)
560{
561 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
562 llvm::Value* src2 = cUnit->irb->getInt32(imm);
563 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
564 defineValue(cUnit, res, rlDest.origSReg);
565}
566
buzbee101305f2012-06-28 18:00:56 -0700567/*
568 * Process arguments for invoke. Note: this code is also used to
569 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
570 * The requirements are similar.
571 */
buzbee6969d502012-06-15 16:40:31 -0700572void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700573 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700574{
575 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
576 llvm::SmallVector<llvm::Value*, 10> args;
577 // Insert the invokeType
578 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
579 // Insert the method_idx
580 args.push_back(cUnit->irb->getInt32(info->index));
581 // Insert the optimization flags
582 args.push_back(cUnit->irb->getInt32(info->optFlags));
583 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700584 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700585 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
586 args.push_back(val);
587 i += info->args[i].wide ? 2 : 1;
588 }
589 /*
590 * Choose the invoke return type based on actual usage. Note: may
591 * be different than shorty. For example, if a function return value
592 * is not used, we'll treat this as a void invoke.
593 */
594 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700595 if (isFilledNewArray) {
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700596 id = greenland::IntrinsicHelper::HLFilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700597 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700598 id = greenland::IntrinsicHelper::HLInvokeVoid;
599 } else {
600 if (info->result.wide) {
601 if (info->result.fp) {
602 id = greenland::IntrinsicHelper::HLInvokeDouble;
603 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700604 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700605 }
606 } else if (info->result.ref) {
607 id = greenland::IntrinsicHelper::HLInvokeObj;
608 } else if (info->result.fp) {
609 id = greenland::IntrinsicHelper::HLInvokeFloat;
610 } else {
611 id = greenland::IntrinsicHelper::HLInvokeInt;
612 }
613 }
614 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
615 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
616 if (info->result.location != kLocInvalid) {
617 defineValue(cUnit, res, info->result.origSReg);
TDYa127890ea892012-08-22 10:49:42 -0700618 if (info->result.ref) {
619 setShadowFrameEntry(cUnit, (llvm::Value*)
620 cUnit->llvmValues.elemList[info->result.origSReg]);
621 }
buzbee6969d502012-06-15 16:40:31 -0700622 }
623}
624
buzbee101305f2012-06-28 18:00:56 -0700625void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
626 greenland::IntrinsicHelper::IntrinsicId id,
627 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700628{
buzbee6969d502012-06-15 16:40:31 -0700629 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700630 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700631 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
632 defineValue(cUnit, res, rlDest.origSReg);
633}
634
buzbee101305f2012-06-28 18:00:56 -0700635void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
636 RegLocation rlSrc)
637{
638 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700639 id = greenland::IntrinsicHelper::HLCheckCast;
buzbee101305f2012-06-28 18:00:56 -0700640 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
641 llvm::SmallVector<llvm::Value*, 2> args;
642 args.push_back(cUnit->irb->getInt32(type_idx));
643 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
644 cUnit->irb->CreateCall(intr, args);
645}
646
buzbee8fa0fda2012-06-27 15:44:52 -0700647void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
648 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700649{
650 greenland::IntrinsicHelper::IntrinsicId id;
651 id = greenland::IntrinsicHelper::NewInstance;
652 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
653 llvm::Value* index = cUnit->irb->getInt32(type_idx);
654 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
655 defineValue(cUnit, res, rlDest.origSReg);
656}
657
buzbee8fa0fda2012-06-27 15:44:52 -0700658void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
659 RegLocation rlDest, RegLocation rlSrc)
660{
661 greenland::IntrinsicHelper::IntrinsicId id;
662 id = greenland::IntrinsicHelper::NewArray;
663 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
664 llvm::SmallVector<llvm::Value*, 2> args;
665 args.push_back(cUnit->irb->getInt32(type_idx));
666 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
667 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
668 defineValue(cUnit, res, rlDest.origSReg);
669}
670
671void convertAget(CompilationUnit* cUnit, int optFlags,
672 greenland::IntrinsicHelper::IntrinsicId id,
673 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
674{
675 llvm::SmallVector<llvm::Value*, 3> args;
676 args.push_back(cUnit->irb->getInt32(optFlags));
677 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
678 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
679 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
680 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
681 defineValue(cUnit, res, rlDest.origSReg);
682}
683
684void convertAput(CompilationUnit* cUnit, int optFlags,
685 greenland::IntrinsicHelper::IntrinsicId id,
686 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
687{
688 llvm::SmallVector<llvm::Value*, 4> args;
689 args.push_back(cUnit->irb->getInt32(optFlags));
690 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
691 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
692 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
693 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
694 cUnit->irb->CreateCall(intr, args);
695}
696
buzbee101305f2012-06-28 18:00:56 -0700697void convertIget(CompilationUnit* cUnit, int optFlags,
698 greenland::IntrinsicHelper::IntrinsicId id,
699 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
700{
701 llvm::SmallVector<llvm::Value*, 3> args;
702 args.push_back(cUnit->irb->getInt32(optFlags));
703 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
704 args.push_back(cUnit->irb->getInt32(fieldIndex));
705 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
706 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
707 defineValue(cUnit, res, rlDest.origSReg);
708}
709
710void convertIput(CompilationUnit* cUnit, int optFlags,
711 greenland::IntrinsicHelper::IntrinsicId id,
712 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
713{
714 llvm::SmallVector<llvm::Value*, 4> args;
715 args.push_back(cUnit->irb->getInt32(optFlags));
716 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
717 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
718 args.push_back(cUnit->irb->getInt32(fieldIndex));
719 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
720 cUnit->irb->CreateCall(intr, args);
721}
722
buzbee8fa0fda2012-06-27 15:44:52 -0700723void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
724 RegLocation rlDest, RegLocation rlSrc)
725{
726 greenland::IntrinsicHelper::IntrinsicId id;
727 id = greenland::IntrinsicHelper::InstanceOf;
728 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
729 llvm::SmallVector<llvm::Value*, 2> args;
730 args.push_back(cUnit->irb->getInt32(type_idx));
731 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
732 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
733 defineValue(cUnit, res, rlDest.origSReg);
734}
735
buzbee101305f2012-06-28 18:00:56 -0700736void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
737 RegLocation rlSrc)
738{
739 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
740 cUnit->irb->getInt64Ty());
741 defineValue(cUnit, res, rlDest.origSReg);
742}
743
buzbee76592632012-06-29 15:18:35 -0700744void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
745 RegLocation rlSrc)
746{
747 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
748 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
749 defineValue(cUnit, res, rlDest.origSReg);
750}
751
752void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
753 RegLocation rlSrc)
754{
755 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
756 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
757 defineValue(cUnit, res, rlDest.origSReg);
758}
759
760void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
761 RegLocation rlSrc)
762{
763 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
764 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
765 defineValue(cUnit, res, rlDest.origSReg);
766}
767
768void convertWideComparison(CompilationUnit* cUnit,
769 greenland::IntrinsicHelper::IntrinsicId id,
770 RegLocation rlDest, RegLocation rlSrc1,
771 RegLocation rlSrc2)
772{
773 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
774 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
775 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
776 llvm::SmallVector<llvm::Value*, 2> args;
777 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
778 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
779 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
780 defineValue(cUnit, res, rlDest.origSReg);
781}
782
buzbee101305f2012-06-28 18:00:56 -0700783void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
784 RegLocation rlSrc,
785 greenland::IntrinsicHelper::IntrinsicId id)
786{
787 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700788 llvm::Value* res =
789 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
790 defineValue(cUnit, res, rlDest.origSReg);
791}
792
793void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
794 RegLocation rlSrc)
795{
796 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
797 defineValue(cUnit, res, rlDest.origSReg);
798}
799
800void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
801 RegLocation rlSrc)
802{
803 llvm::Value* res =
804 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
805 defineValue(cUnit, res, rlDest.origSReg);
806}
807
TDYa1274ec8ccd2012-08-11 07:04:57 -0700808void convertFPToInt(CompilationUnit* cUnit,
809 greenland::IntrinsicHelper::IntrinsicId id,
810 RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700811 RegLocation rlSrc)
812{
TDYa1274ec8ccd2012-08-11 07:04:57 -0700813 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
814 llvm::Value* res = cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
buzbee76592632012-06-29 15:18:35 -0700815 defineValue(cUnit, res, rlDest.origSReg);
816}
817
818
819void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
820 RegLocation rlSrc)
821{
822 llvm::Value* res =
823 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
824 defineValue(cUnit, res, rlDest.origSReg);
825}
826
827void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
828 RegLocation rlSrc)
829{
830 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
831 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700832 defineValue(cUnit, res, rlDest.origSReg);
833}
834
buzbee2cfc6392012-05-07 14:51:40 -0700835/*
836 * Target-independent code generation. Use only high-level
837 * load/store utilities here, or target-dependent genXX() handlers
838 * when necessary.
839 */
840bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
841 llvm::BasicBlock* llvmBB, LIR* labelList)
842{
843 bool res = false; // Assume success
844 RegLocation rlSrc[3];
845 RegLocation rlDest = badLoc;
buzbee2cfc6392012-05-07 14:51:40 -0700846 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee6969d502012-06-15 16:40:31 -0700847 uint32_t vB = mir->dalvikInsn.vB;
848 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700849 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700850
buzbeeb03f4872012-06-11 15:22:11 -0700851 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700852
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700853 if (cUnit->printMe) {
854 if ((int)opcode < kMirOpFirst) {
855 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x"
856 << std::hex << (int)opcode;
857 } else {
858 LOG(INFO) << ".. opcode 0x" << std::hex << (int)opcode;
859 }
860 }
861
buzbee2cfc6392012-05-07 14:51:40 -0700862 /* Prep Src and Dest locations */
863 int nextSreg = 0;
864 int nextLoc = 0;
865 int attrs = oatDataFlowAttributes[opcode];
866 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
867 if (attrs & DF_UA) {
868 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700869 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700870 nextSreg+= 2;
871 } else {
872 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
873 nextSreg++;
874 }
875 }
876 if (attrs & DF_UB) {
877 if (attrs & DF_B_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_UC) {
886 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700887 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700888 } else {
889 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
890 }
891 }
892 if (attrs & DF_DA) {
893 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700894 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700895 } else {
buzbee15bf9802012-06-12 17:49:27 -0700896 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700897 if (rlDest.ref) {
898 objectDefinition = true;
899 }
buzbee2cfc6392012-05-07 14:51:40 -0700900 }
901 }
902
903 switch (opcode) {
904 case Instruction::NOP:
905 break;
906
907 case Instruction::MOVE:
908 case Instruction::MOVE_OBJECT:
909 case Instruction::MOVE_16:
910 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700911 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700912 case Instruction::MOVE_FROM16:
913 case Instruction::MOVE_WIDE:
914 case Instruction::MOVE_WIDE_16:
915 case Instruction::MOVE_WIDE_FROM16: {
916 /*
917 * Moves/copies are meaningless in pure SSA register form,
918 * but we need to preserve them for the conversion back into
919 * MIR (at least until we stop using the Dalvik register maps).
920 * Insert a dummy intrinsic copy call, which will be recognized
921 * by the quick path and removed by the portable path.
922 */
923 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
924 llvm::Value* res = emitCopy(cUnit, src, rlDest);
925 defineValue(cUnit, res, rlDest.origSReg);
926 }
927 break;
928
929 case Instruction::CONST:
930 case Instruction::CONST_4:
931 case Instruction::CONST_16: {
TDYa127347166a2012-08-23 12:23:44 -0700932 if (vB == 0) {
933 objectDefinition = true;
934 }
buzbee6969d502012-06-15 16:40:31 -0700935 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700936 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
937 defineValue(cUnit, res, rlDest.origSReg);
938 }
939 break;
940
941 case Instruction::CONST_WIDE_16:
942 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700943 // Sign extend to 64 bits
944 int64_t imm = static_cast<int32_t>(vB);
945 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700946 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
947 defineValue(cUnit, res, rlDest.origSReg);
948 }
949 break;
950
951 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700952 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700953 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
954 defineValue(cUnit, res, rlDest.origSReg);
955 }
956 break;
957
958 case Instruction::CONST_WIDE: {
959 llvm::Constant* immValue =
960 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
961 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
962 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700963 }
964 break;
buzbee2cfc6392012-05-07 14:51:40 -0700965 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700966 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700967 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
968 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
969 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700970 }
971 break;
972
buzbee8fa0fda2012-06-27 15:44:52 -0700973 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700974 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700975 rlSrc[0]);
976 break;
977 case Instruction::SPUT:
978 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700979 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700980 rlSrc[0]);
981 } else {
buzbee76592632012-06-29 15:18:35 -0700982 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700983 }
984 break;
985 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700986 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700987 rlSrc[0]);
988 break;
989 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700990 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700991 break;
992 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700993 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700994 break;
995 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -0700996 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700997 break;
998 case Instruction::SPUT_WIDE:
999 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -07001000 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -07001001 rlSrc[0]);
1002 } else {
buzbee76592632012-06-29 15:18:35 -07001003 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -07001004 rlSrc[0]);
1005 }
1006 break;
1007
1008 case Instruction::SGET_OBJECT:
1009 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
1010 break;
1011 case Instruction::SGET:
1012 if (rlDest.fp) {
1013 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
1014 } else {
1015 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
1016 }
1017 break;
1018 case Instruction::SGET_BOOLEAN:
1019 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
1020 break;
1021 case Instruction::SGET_BYTE:
1022 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
1023 break;
1024 case Instruction::SGET_CHAR:
1025 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
1026 break;
1027 case Instruction::SGET_SHORT:
1028 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
1029 break;
1030 case Instruction::SGET_WIDE:
1031 if (rlDest.fp) {
1032 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
1033 rlDest);
1034 } else {
1035 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001036 }
1037 break;
buzbee2cfc6392012-05-07 14:51:40 -07001038
1039 case Instruction::RETURN_WIDE:
1040 case Instruction::RETURN:
1041 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -07001042 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001043 emitSuspendCheck(cUnit);
1044 }
buzbeeb03f4872012-06-11 15:22:11 -07001045 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001046 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
1047 bb->hasReturn = true;
1048 }
1049 break;
1050
1051 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001052 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001053 emitSuspendCheck(cUnit);
1054 }
buzbeeb03f4872012-06-11 15:22:11 -07001055 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001056 cUnit->irb->CreateRetVoid();
1057 bb->hasReturn = true;
1058 }
1059 break;
1060
1061 case Instruction::IF_EQ:
1062 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1063 break;
1064 case Instruction::IF_NE:
1065 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1066 break;
1067 case Instruction::IF_LT:
1068 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1069 break;
1070 case Instruction::IF_GE:
1071 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1072 break;
1073 case Instruction::IF_GT:
1074 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1075 break;
1076 case Instruction::IF_LE:
1077 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1078 break;
1079 case Instruction::IF_EQZ:
1080 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1081 break;
1082 case Instruction::IF_NEZ:
1083 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1084 break;
1085 case Instruction::IF_LTZ:
1086 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1087 break;
1088 case Instruction::IF_GEZ:
1089 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1090 break;
1091 case Instruction::IF_GTZ:
1092 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1093 break;
1094 case Instruction::IF_LEZ:
1095 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1096 break;
1097
1098 case Instruction::GOTO:
1099 case Instruction::GOTO_16:
1100 case Instruction::GOTO_32: {
1101 if (bb->taken->startOffset <= bb->startOffset) {
1102 emitSuspendCheck(cUnit);
1103 }
1104 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1105 }
1106 break;
1107
1108 case Instruction::ADD_LONG:
1109 case Instruction::ADD_LONG_2ADDR:
1110 case Instruction::ADD_INT:
1111 case Instruction::ADD_INT_2ADDR:
1112 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1113 break;
1114 case Instruction::SUB_LONG:
1115 case Instruction::SUB_LONG_2ADDR:
1116 case Instruction::SUB_INT:
1117 case Instruction::SUB_INT_2ADDR:
1118 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1119 break;
1120 case Instruction::MUL_LONG:
1121 case Instruction::MUL_LONG_2ADDR:
1122 case Instruction::MUL_INT:
1123 case Instruction::MUL_INT_2ADDR:
1124 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1125 break;
1126 case Instruction::DIV_LONG:
1127 case Instruction::DIV_LONG_2ADDR:
1128 case Instruction::DIV_INT:
1129 case Instruction::DIV_INT_2ADDR:
1130 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1131 break;
1132 case Instruction::REM_LONG:
1133 case Instruction::REM_LONG_2ADDR:
1134 case Instruction::REM_INT:
1135 case Instruction::REM_INT_2ADDR:
1136 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1137 break;
1138 case Instruction::AND_LONG:
1139 case Instruction::AND_LONG_2ADDR:
1140 case Instruction::AND_INT:
1141 case Instruction::AND_INT_2ADDR:
1142 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1143 break;
1144 case Instruction::OR_LONG:
1145 case Instruction::OR_LONG_2ADDR:
1146 case Instruction::OR_INT:
1147 case Instruction::OR_INT_2ADDR:
1148 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1149 break;
1150 case Instruction::XOR_LONG:
1151 case Instruction::XOR_LONG_2ADDR:
1152 case Instruction::XOR_INT:
1153 case Instruction::XOR_INT_2ADDR:
1154 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1155 break;
1156 case Instruction::SHL_LONG:
1157 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001158 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1159 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001160 break;
buzbee2cfc6392012-05-07 14:51:40 -07001161 case Instruction::SHL_INT:
1162 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001163 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1164 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001165 break;
1166 case Instruction::SHR_LONG:
1167 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001168 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1169 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001170 break;
buzbee2cfc6392012-05-07 14:51:40 -07001171 case Instruction::SHR_INT:
1172 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001173 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1174 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001175 break;
1176 case Instruction::USHR_LONG:
1177 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001178 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1179 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001180 break;
buzbee2cfc6392012-05-07 14:51:40 -07001181 case Instruction::USHR_INT:
1182 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001183 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1184 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001185 break;
1186
1187 case Instruction::ADD_INT_LIT16:
1188 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001189 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001190 break;
1191 case Instruction::RSUB_INT:
1192 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001193 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001194 break;
1195 case Instruction::MUL_INT_LIT16:
1196 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001197 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001198 break;
1199 case Instruction::DIV_INT_LIT16:
1200 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001201 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001202 break;
1203 case Instruction::REM_INT_LIT16:
1204 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001205 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001206 break;
1207 case Instruction::AND_INT_LIT16:
1208 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001209 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001210 break;
1211 case Instruction::OR_INT_LIT16:
1212 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001213 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001214 break;
1215 case Instruction::XOR_INT_LIT16:
1216 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001217 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001218 break;
1219 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001220 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1221 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001222 break;
1223 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001224 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1225 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001226 break;
1227 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001228 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1229 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001230 break;
1231
1232 case Instruction::ADD_FLOAT:
1233 case Instruction::ADD_FLOAT_2ADDR:
1234 case Instruction::ADD_DOUBLE:
1235 case Instruction::ADD_DOUBLE_2ADDR:
1236 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1237 break;
1238
1239 case Instruction::SUB_FLOAT:
1240 case Instruction::SUB_FLOAT_2ADDR:
1241 case Instruction::SUB_DOUBLE:
1242 case Instruction::SUB_DOUBLE_2ADDR:
1243 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1244 break;
1245
1246 case Instruction::MUL_FLOAT:
1247 case Instruction::MUL_FLOAT_2ADDR:
1248 case Instruction::MUL_DOUBLE:
1249 case Instruction::MUL_DOUBLE_2ADDR:
1250 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1251 break;
1252
1253 case Instruction::DIV_FLOAT:
1254 case Instruction::DIV_FLOAT_2ADDR:
1255 case Instruction::DIV_DOUBLE:
1256 case Instruction::DIV_DOUBLE_2ADDR:
1257 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1258 break;
1259
1260 case Instruction::REM_FLOAT:
1261 case Instruction::REM_FLOAT_2ADDR:
1262 case Instruction::REM_DOUBLE:
1263 case Instruction::REM_DOUBLE_2ADDR:
1264 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1265 break;
1266
buzbee6969d502012-06-15 16:40:31 -07001267 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001268 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1269 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001270 break;
1271 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001272 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1273 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001274 break;
1275
1276 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001277 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1278 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001279 break;
1280 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001281 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1282 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001283 break;
1284
1285 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001286 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1287 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001288 break;
1289 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001290 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1291 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001292 break;
1293
1294 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001295 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1296 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001297 break;
1298 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001299 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1300 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001301 break;
1302
1303 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001304 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1305 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001306 break;
1307 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001308 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1309 false /* NewFilledArray */);
1310 break;
1311 case Instruction::FILLED_NEW_ARRAY:
1312 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1313 true /* NewFilledArray */);
1314 break;
1315 case Instruction::FILLED_NEW_ARRAY_RANGE:
1316 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1317 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001318 break;
1319
1320 case Instruction::CONST_STRING:
1321 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001322 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1323 rlDest);
1324 break;
1325
1326 case Instruction::CONST_CLASS:
1327 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1328 rlDest);
1329 break;
1330
1331 case Instruction::CHECK_CAST:
1332 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001333 break;
1334
buzbee4f1181f2012-06-22 13:52:12 -07001335 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001336 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001337 break;
1338
buzbee32412962012-06-26 16:27:56 -07001339 case Instruction::MOVE_EXCEPTION:
1340 convertMoveException(cUnit, rlDest);
1341 break;
1342
1343 case Instruction::THROW:
1344 convertThrow(cUnit, rlSrc[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001345 /*
1346 * If this throw is standalone, terminate.
1347 * If it might rethrow, force termination
1348 * of the following block.
1349 */
1350 if (bb->fallThrough == NULL) {
1351 cUnit->irb->CreateUnreachable();
1352 } else {
1353 bb->fallThrough->fallThrough = NULL;
1354 bb->fallThrough->taken = NULL;
1355 }
buzbee32412962012-06-26 16:27:56 -07001356 break;
1357
buzbee2cfc6392012-05-07 14:51:40 -07001358 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001359 case Instruction::MOVE_RESULT:
1360 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001361 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001362 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001363 */
jeffhao9a4f0032012-08-30 16:17:40 -07001364 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001365 break;
1366
1367 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001368 convertMonitorEnterExit(cUnit, optFlags,
1369 greenland::IntrinsicHelper::MonitorEnter,
1370 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001371 break;
1372
1373 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001374 convertMonitorEnterExit(cUnit, optFlags,
1375 greenland::IntrinsicHelper::MonitorExit,
1376 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001377 break;
1378
1379 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001380 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001381 break;
1382
1383 case Instruction::NEW_ARRAY:
1384 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1385 break;
1386
1387 case Instruction::INSTANCE_OF:
1388 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1389 break;
1390
1391 case Instruction::AGET:
1392 if (rlDest.fp) {
1393 convertAget(cUnit, optFlags,
1394 greenland::IntrinsicHelper::HLArrayGetFloat,
1395 rlDest, rlSrc[0], rlSrc[1]);
1396 } else {
1397 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1398 rlDest, rlSrc[0], rlSrc[1]);
1399 }
1400 break;
1401 case Instruction::AGET_OBJECT:
1402 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1403 rlDest, rlSrc[0], rlSrc[1]);
1404 break;
1405 case Instruction::AGET_BOOLEAN:
1406 convertAget(cUnit, optFlags,
1407 greenland::IntrinsicHelper::HLArrayGetBoolean,
1408 rlDest, rlSrc[0], rlSrc[1]);
1409 break;
1410 case Instruction::AGET_BYTE:
1411 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1412 rlDest, rlSrc[0], rlSrc[1]);
1413 break;
1414 case Instruction::AGET_CHAR:
1415 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1416 rlDest, rlSrc[0], rlSrc[1]);
1417 break;
1418 case Instruction::AGET_SHORT:
1419 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1420 rlDest, rlSrc[0], rlSrc[1]);
1421 break;
1422 case Instruction::AGET_WIDE:
1423 if (rlDest.fp) {
1424 convertAget(cUnit, optFlags,
1425 greenland::IntrinsicHelper::HLArrayGetDouble,
1426 rlDest, rlSrc[0], rlSrc[1]);
1427 } else {
1428 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1429 rlDest, rlSrc[0], rlSrc[1]);
1430 }
1431 break;
1432
1433 case Instruction::APUT:
1434 if (rlSrc[0].fp) {
1435 convertAput(cUnit, optFlags,
1436 greenland::IntrinsicHelper::HLArrayPutFloat,
1437 rlSrc[0], rlSrc[1], rlSrc[2]);
1438 } else {
1439 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1440 rlSrc[0], rlSrc[1], rlSrc[2]);
1441 }
1442 break;
1443 case Instruction::APUT_OBJECT:
1444 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1445 rlSrc[0], rlSrc[1], rlSrc[2]);
1446 break;
1447 case Instruction::APUT_BOOLEAN:
1448 convertAput(cUnit, optFlags,
1449 greenland::IntrinsicHelper::HLArrayPutBoolean,
1450 rlSrc[0], rlSrc[1], rlSrc[2]);
1451 break;
1452 case Instruction::APUT_BYTE:
1453 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1454 rlSrc[0], rlSrc[1], rlSrc[2]);
1455 break;
1456 case Instruction::APUT_CHAR:
1457 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1458 rlSrc[0], rlSrc[1], rlSrc[2]);
1459 break;
1460 case Instruction::APUT_SHORT:
1461 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1462 rlSrc[0], rlSrc[1], rlSrc[2]);
1463 break;
1464 case Instruction::APUT_WIDE:
1465 if (rlSrc[0].fp) {
1466 convertAput(cUnit, optFlags,
1467 greenland::IntrinsicHelper::HLArrayPutDouble,
1468 rlSrc[0], rlSrc[1], rlSrc[2]);
1469 } else {
1470 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1471 rlSrc[0], rlSrc[1], rlSrc[2]);
1472 }
1473 break;
1474
buzbee101305f2012-06-28 18:00:56 -07001475 case Instruction::IGET:
1476 if (rlDest.fp) {
1477 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001478 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001479 } else {
1480 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001481 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001482 }
buzbee2cfc6392012-05-07 14:51:40 -07001483 break;
buzbee101305f2012-06-28 18:00:56 -07001484 case Instruction::IGET_OBJECT:
1485 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001486 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001487 break;
1488 case Instruction::IGET_BOOLEAN:
1489 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001490 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001491 break;
1492 case Instruction::IGET_BYTE:
1493 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001494 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001495 break;
1496 case Instruction::IGET_CHAR:
1497 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001498 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001499 break;
1500 case Instruction::IGET_SHORT:
1501 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001502 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001503 break;
1504 case Instruction::IGET_WIDE:
1505 if (rlDest.fp) {
1506 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001507 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001508 } else {
1509 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001510 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001511 }
1512 break;
1513 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001514 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001515 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1516 rlSrc[0], rlSrc[1], vC);
1517 } else {
1518 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1519 rlSrc[0], rlSrc[1], vC);
1520 }
1521 break;
1522 case Instruction::IPUT_OBJECT:
1523 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1524 rlSrc[0], rlSrc[1], vC);
1525 break;
1526 case Instruction::IPUT_BOOLEAN:
1527 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1528 rlSrc[0], rlSrc[1], vC);
1529 break;
1530 case Instruction::IPUT_BYTE:
1531 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1532 rlSrc[0], rlSrc[1], vC);
1533 break;
1534 case Instruction::IPUT_CHAR:
1535 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1536 rlSrc[0], rlSrc[1], vC);
1537 break;
1538 case Instruction::IPUT_SHORT:
1539 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1540 rlSrc[0], rlSrc[1], vC);
1541 break;
1542 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001543 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001544 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1545 rlSrc[0], rlSrc[1], vC);
1546 } else {
1547 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1548 rlSrc[0], rlSrc[1], vC);
1549 }
buzbee2cfc6392012-05-07 14:51:40 -07001550 break;
1551
1552 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001553 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001554 break;
1555
buzbee76592632012-06-29 15:18:35 -07001556 case Instruction::LONG_TO_INT:
1557 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1558 break;
1559
buzbee101305f2012-06-28 18:00:56 -07001560 case Instruction::INT_TO_LONG:
1561 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001562 break;
1563
buzbee101305f2012-06-28 18:00:56 -07001564 case Instruction::INT_TO_CHAR:
1565 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1566 greenland::IntrinsicHelper::IntToChar);
1567 break;
1568 case Instruction::INT_TO_BYTE:
1569 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1570 greenland::IntrinsicHelper::IntToByte);
1571 break;
1572 case Instruction::INT_TO_SHORT:
1573 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1574 greenland::IntrinsicHelper::IntToShort);
1575 break;
1576
buzbee76592632012-06-29 15:18:35 -07001577 case Instruction::INT_TO_FLOAT:
1578 case Instruction::LONG_TO_FLOAT:
1579 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001580 break;
1581
buzbee76592632012-06-29 15:18:35 -07001582 case Instruction::INT_TO_DOUBLE:
1583 case Instruction::LONG_TO_DOUBLE:
1584 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001585 break;
1586
buzbee76592632012-06-29 15:18:35 -07001587 case Instruction::FLOAT_TO_DOUBLE:
1588 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001589 break;
1590
buzbee76592632012-06-29 15:18:35 -07001591 case Instruction::DOUBLE_TO_FLOAT:
1592 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001593 break;
1594
1595 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001596 case Instruction::NEG_INT:
1597 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001598 break;
1599
1600 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001601 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001602 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001603 break;
1604
buzbee76592632012-06-29 15:18:35 -07001605 case Instruction::NOT_LONG:
1606 case Instruction::NOT_INT:
1607 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001608 break;
1609
buzbee2cfc6392012-05-07 14:51:40 -07001610 case Instruction::FLOAT_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001611 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2I, rlDest, rlSrc[0]);
1612 break;
1613
buzbee2cfc6392012-05-07 14:51:40 -07001614 case Instruction::DOUBLE_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001615 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2I, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001616 break;
1617
buzbee76592632012-06-29 15:18:35 -07001618 case Instruction::FLOAT_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001619 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2L, rlDest, rlSrc[0]);
1620 break;
1621
buzbee76592632012-06-29 15:18:35 -07001622 case Instruction::DOUBLE_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001623 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2L, rlDest, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001624 break;
1625
1626 case Instruction::CMPL_FLOAT:
1627 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1628 rlDest, rlSrc[0], rlSrc[1]);
1629 break;
1630 case Instruction::CMPG_FLOAT:
1631 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1632 rlDest, rlSrc[0], rlSrc[1]);
1633 break;
1634 case Instruction::CMPL_DOUBLE:
1635 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1636 rlDest, rlSrc[0], rlSrc[1]);
1637 break;
1638 case Instruction::CMPG_DOUBLE:
1639 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1640 rlDest, rlSrc[0], rlSrc[1]);
1641 break;
1642 case Instruction::CMP_LONG:
1643 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1644 rlDest, rlSrc[0], rlSrc[1]);
1645 break;
1646
buzbee76592632012-06-29 15:18:35 -07001647 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001648 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001649 break;
1650
1651 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001652 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001653 break;
buzbee2cfc6392012-05-07 14:51:40 -07001654
1655 default:
buzbee32412962012-06-26 16:27:56 -07001656 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001657 res = true;
1658 }
buzbeeb03f4872012-06-11 15:22:11 -07001659 if (objectDefinition) {
1660 setShadowFrameEntry(cUnit, (llvm::Value*)
1661 cUnit->llvmValues.elemList[rlDest.origSReg]);
1662 }
buzbee2cfc6392012-05-07 14:51:40 -07001663 return res;
1664}
1665
1666/* Extended MIR instructions like PHI */
1667void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1668 llvm::BasicBlock* llvmBB)
1669{
1670
1671 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1672 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001673 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001674 /*
1675 * The Art compiler's Phi nodes only handle 32-bit operands,
1676 * representing wide values using a matched set of Phi nodes
1677 * for the lower and upper halves. In the llvm world, we only
1678 * want a single Phi for wides. Here we will simply discard
1679 * the Phi node representing the high word.
1680 */
1681 if (rlDest.highWord) {
1682 return; // No Phi node - handled via low word
1683 }
1684 int* incoming = (int*)mir->dalvikInsn.vB;
buzbee2cfc6392012-05-07 14:51:40 -07001685 llvm::Type* phiType =
1686 llvmTypeFromLocRec(cUnit, rlDest);
1687 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1688 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1689 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001690 // Don't check width here.
1691 loc = oatGetRawSrc(cUnit, mir, i);
1692 DCHECK_EQ(rlDest.wide, loc.wide);
1693 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1694 DCHECK_EQ(rlDest.fp, loc.fp);
1695 DCHECK_EQ(rlDest.core, loc.core);
1696 DCHECK_EQ(rlDest.ref, loc.ref);
buzbeed1643e42012-09-05 14:06:51 -07001697 SafeMap<unsigned int, unsigned int>::iterator it;
1698 it = cUnit->blockIdMap.find(incoming[i]);
1699 DCHECK(it != cUnit->blockIdMap.end());
buzbee2cfc6392012-05-07 14:51:40 -07001700 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
buzbeed1643e42012-09-05 14:06:51 -07001701 getLLVMBlock(cUnit, it->second));
buzbee2cfc6392012-05-07 14:51:40 -07001702 }
1703 defineValue(cUnit, phi, rlDest.origSReg);
1704 break;
1705 }
1706 case kMirOpCopy: {
1707 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1708 break;
1709 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001710 case kMirOpNop:
1711 if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
1712 (bb->fallThrough == NULL)) {
1713 cUnit->irb->CreateUnreachable();
1714 }
1715 break;
1716
buzbee2cfc6392012-05-07 14:51:40 -07001717#if defined(TARGET_ARM)
1718 case kMirOpFusedCmplFloat:
1719 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1720 break;
1721 case kMirOpFusedCmpgFloat:
1722 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1723 break;
1724 case kMirOpFusedCmplDouble:
1725 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1726 break;
1727 case kMirOpFusedCmpgDouble:
1728 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1729 break;
1730 case kMirOpFusedCmpLong:
1731 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1732 break;
1733#endif
1734 default:
1735 break;
1736 }
1737}
1738
1739void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1740{
1741 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001742 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001743 arrayRef.push_back(cUnit->irb->getInt32(offset));
1744 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1745 cUnit->irb->SetDexOffset(node);
1746}
1747
1748// Attach method info as metadata to special intrinsic
1749void setMethodInfo(CompilationUnit* cUnit)
1750{
1751 // We don't want dex offset on this
1752 cUnit->irb->SetDexOffset(NULL);
1753 greenland::IntrinsicHelper::IntrinsicId id;
1754 id = greenland::IntrinsicHelper::MethodInfo;
1755 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1756 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1757 llvm::SmallVector<llvm::Value*, 2> regInfo;
1758 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1759 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1760 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1761 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1762 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1763 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1764 inst->setMetadata("RegInfo", regInfoNode);
1765 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1766 llvm::SmallVector<llvm::Value*, 50> pmap;
1767 for (int i = 0; i < promoSize; i++) {
1768 PromotionMap* p = &cUnit->promotionMap[i];
1769 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1770 ((p->fpReg & 0xff) << 16) |
1771 ((p->coreReg & 0xff) << 8) |
1772 ((p->fpLocation & 0xf) << 4) |
1773 (p->coreLocation & 0xf);
1774 pmap.push_back(cUnit->irb->getInt32(mapData));
1775 }
1776 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1777 inst->setMetadata("PromotionMap", mapNode);
1778 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1779}
1780
1781/* Handle the content in each basic block */
1782bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1783{
buzbeed1643e42012-09-05 14:06:51 -07001784 if (bb->blockType == kDead) return false;
buzbee2cfc6392012-05-07 14:51:40 -07001785 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
buzbeef5f5a122012-09-21 13:57:36 -07001786 if (llvmBB == NULL) {
1787 CHECK(bb->blockType == kExitBlock);
1788 } else {
1789 cUnit->irb->SetInsertPoint(llvmBB);
1790 setDexOffset(cUnit, bb->startOffset);
1791 }
buzbee2cfc6392012-05-07 14:51:40 -07001792
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001793 if (cUnit->printMe) {
1794 LOG(INFO) << "................................";
1795 LOG(INFO) << "Block id " << bb->id;
1796 if (llvmBB != NULL) {
1797 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1798 } else {
1799 LOG(INFO) << "llvmBB is NULL";
1800 }
1801 }
1802
buzbee2cfc6392012-05-07 14:51:40 -07001803 if (bb->blockType == kEntryBlock) {
1804 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001805 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1806 cUnit->numDalvikRegisters, true,
1807 kAllocMisc);
1808 for (int i = 0; i < cUnit->numSSARegs; i++) {
buzbee6ec5e232012-09-20 15:50:03 -07001809 int vReg = SRegToVReg(cUnit, i);
1810 if (vReg > SSA_METHOD_BASEREG) {
1811 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1812 }
buzbeeb03f4872012-06-11 15:22:11 -07001813 }
1814 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1815 if (canBeRef[i]) {
1816 cUnit->numShadowFrameEntries++;
1817 }
1818 }
1819 if (cUnit->numShadowFrameEntries > 0) {
1820 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1821 cUnit->numShadowFrameEntries, true,
1822 kAllocMisc);
1823 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1824 if (canBeRef[i]) {
1825 cUnit->shadowMap[j++] = i;
1826 }
1827 }
buzbeeb03f4872012-06-11 15:22:11 -07001828 }
Shih-wei Liao569daf12012-08-10 23:22:33 -07001829 greenland::IntrinsicHelper::IntrinsicId id =
1830 greenland::IntrinsicHelper::AllocaShadowFrame;
1831 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1832 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1833 cUnit->irb->CreateCall(func, entries);
buzbee2cfc6392012-05-07 14:51:40 -07001834 } else if (bb->blockType == kExitBlock) {
1835 /*
1836 * Because of the differences between how MIR/LIR and llvm handle exit
1837 * blocks, we won't explicitly covert them. On the llvm-to-lir
1838 * path, it will need to be regenereated.
1839 */
1840 return false;
buzbee6969d502012-06-15 16:40:31 -07001841 } else if (bb->blockType == kExceptionHandling) {
1842 /*
1843 * Because we're deferring null checking, delete the associated empty
1844 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001845 */
1846 llvmBB->eraseFromParent();
1847 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001848 }
1849
1850 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1851
1852 setDexOffset(cUnit, mir->offset);
1853
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001854 int opcode = mir->dalvikInsn.opcode;
1855 Instruction::Format dalvikFormat =
1856 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001857
1858 /* If we're compiling for the debugger, generate an update callout */
1859 if (cUnit->genDebugger) {
1860 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1861 //genDebuggerUpdate(cUnit, mir->offset);
1862 }
1863
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001864 if (opcode == kMirOpCheck) {
1865 // Combine check and work halves of throwing instruction.
1866 MIR* workHalf = mir->meta.throwInsn;
1867 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
1868 opcode = mir->dalvikInsn.opcode;
1869 SSARepresentation* ssaRep = workHalf->ssaRep;
1870 workHalf->ssaRep = mir->ssaRep;
1871 mir->ssaRep = ssaRep;
1872 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1873 if (bb->successorBlockList.blockListType == kCatch) {
1874 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
1875 greenland::IntrinsicHelper::CatchTargets);
1876 llvm::Value* switchKey =
1877 cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
1878 GrowableListIterator iter;
1879 oatGrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
1880 // New basic block to use for work half
1881 llvm::BasicBlock* workBB =
1882 llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
1883 llvm::SwitchInst* sw =
1884 cUnit->irb->CreateSwitch(switchKey, workBB,
1885 bb->successorBlockList.blocks.numUsed);
1886 while (true) {
1887 SuccessorBlockInfo *successorBlockInfo =
1888 (SuccessorBlockInfo *) oatGrowableListIteratorNext(&iter);
1889 if (successorBlockInfo == NULL) break;
1890 llvm::BasicBlock *target =
1891 getLLVMBlock(cUnit, successorBlockInfo->block->id);
1892 int typeIndex = successorBlockInfo->key;
1893 sw->addCase(cUnit->irb->getInt32(typeIndex), target);
1894 }
1895 llvmBB = workBB;
1896 cUnit->irb->SetInsertPoint(llvmBB);
1897 }
1898 }
1899
1900 if (opcode >= kMirOpFirst) {
buzbee2cfc6392012-05-07 14:51:40 -07001901 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1902 continue;
1903 }
1904
1905 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1906 NULL /* labelList */);
1907 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001908 Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001909 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001910 mir->offset, opcode,
buzbee2cfc6392012-05-07 14:51:40 -07001911 Instruction::Name(dalvikOpcode),
1912 dalvikFormat);
1913 }
1914 }
1915
buzbee4be777b2012-07-12 14:38:18 -07001916 if (bb->blockType == kEntryBlock) {
1917 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1918 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001919 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1920 }
1921
1922 return false;
1923}
1924
buzbee4f4dfc72012-07-02 14:54:44 -07001925char remapShorty(char shortyType) {
1926 /*
1927 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1928 * and longs/doubles are represented as a pair of registers. When sub-word
1929 * arguments (and method results) are passed, they are extended to Dalvik
1930 * virtual register containers. Because llvm is picky about type consistency,
1931 * we must either cast the "real" type to 32-bit container multiple Dalvik
1932 * register types, or always use the expanded values.
1933 * Here, we're doing the latter. We map the shorty signature to container
1934 * types (which is valid so long as we always do a real expansion of passed
1935 * arguments and field loads).
1936 */
1937 switch(shortyType) {
1938 case 'Z' : shortyType = 'I'; break;
1939 case 'B' : shortyType = 'I'; break;
1940 case 'S' : shortyType = 'I'; break;
1941 case 'C' : shortyType = 'I'; break;
1942 default: break;
1943 }
1944 return shortyType;
1945}
1946
buzbee2cfc6392012-05-07 14:51:40 -07001947llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1948
1949 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001950 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001951 greenland::kAccurate);
1952
1953 // Get argument type
1954 std::vector<llvm::Type*> args_type;
1955
1956 // method object
1957 args_type.push_back(cUnit->irb->GetJMethodTy());
1958
1959 // Do we have a "this"?
1960 if ((cUnit->access_flags & kAccStatic) == 0) {
1961 args_type.push_back(cUnit->irb->GetJObjectTy());
1962 }
1963
1964 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001965 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001966 greenland::kAccurate));
1967 }
1968
1969 return llvm::FunctionType::get(ret_type, args_type, false);
1970}
1971
1972bool createFunction(CompilationUnit* cUnit) {
1973 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1974 /* with_signature */ false));
1975 llvm::FunctionType* func_type = getFunctionType(cUnit);
1976
1977 if (func_type == NULL) {
1978 return false;
1979 }
1980
1981 cUnit->func = llvm::Function::Create(func_type,
1982 llvm::Function::ExternalLinkage,
1983 func_name, cUnit->module);
1984
1985 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1986 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1987
1988 arg_iter->setName("method");
1989 ++arg_iter;
1990
1991 int startSReg = cUnit->numRegs;
1992
1993 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1994 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1995 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1996 }
1997
1998 return true;
1999}
2000
2001bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
2002{
2003 // Skip the exit block
buzbeed1643e42012-09-05 14:06:51 -07002004 if ((bb->blockType == kDead) ||(bb->blockType == kExitBlock)) {
buzbee2cfc6392012-05-07 14:51:40 -07002005 cUnit->idToBlockMap.Put(bb->id, NULL);
2006 } else {
2007 int offset = bb->startOffset;
2008 bool entryBlock = (bb->blockType == kEntryBlock);
2009 llvm::BasicBlock* llvmBB =
2010 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
buzbee8320f382012-09-11 16:29:42 -07002011 StringPrintf(kLabelFormat, bb->catchEntry ? kCatchBlock :
2012 kNormalBlock, offset, bb->id), cUnit->func);
buzbee2cfc6392012-05-07 14:51:40 -07002013 if (entryBlock) {
2014 cUnit->entryBB = llvmBB;
2015 cUnit->placeholderBB =
2016 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
2017 cUnit->func);
2018 }
2019 cUnit->idToBlockMap.Put(bb->id, llvmBB);
2020 }
2021 return false;
2022}
2023
2024
2025/*
2026 * Convert MIR to LLVM_IR
2027 * o For each ssa name, create LLVM named value. Type these
2028 * appropriately, and ignore high half of wide and double operands.
2029 * o For each MIR basic block, create an LLVM basic block.
2030 * o Iterate through the MIR a basic block at a time, setting arguments
2031 * to recovered ssa name.
2032 */
2033void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
2034{
2035 initIR(cUnit);
2036 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
2037
2038 // Create the function
2039 createFunction(cUnit);
2040
2041 // Create an LLVM basic block for each MIR block in dfs preorder
2042 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
2043 kPreOrderDFSTraversal, false /* isIterative */);
2044 /*
2045 * Create an llvm named value for each MIR SSA name. Note: we'll use
2046 * placeholders for all non-argument values (because we haven't seen
2047 * the definition yet).
2048 */
2049 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2050 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2051 arg_iter++; /* Skip path method */
2052 for (int i = 0; i < cUnit->numSSARegs; i++) {
2053 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07002054 RegLocation rlTemp = cUnit->regLocation[i];
2055 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07002056 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
2057 } else if ((i < cUnit->numRegs) ||
2058 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07002059 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
2060 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07002061 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
2062 val->setName(llvmSSAName(cUnit, i));
buzbee2cfc6392012-05-07 14:51:40 -07002063 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
buzbee2cfc6392012-05-07 14:51:40 -07002064 } else {
2065 // Recover previously-created argument values
2066 llvm::Value* argVal = arg_iter++;
2067 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
2068 }
2069 }
buzbee2cfc6392012-05-07 14:51:40 -07002070
2071 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
2072 kPreOrderDFSTraversal, false /* Iterative */);
2073
buzbee4be777b2012-07-12 14:38:18 -07002074 /*
2075 * In a few rare cases of verification failure, the verifier will
2076 * replace one or more Dalvik opcodes with the special
2077 * throw-verification-failure opcode. This can leave the SSA graph
2078 * in an invalid state, as definitions may be lost, while uses retained.
2079 * To work around this problem, we insert placeholder definitions for
2080 * all Dalvik SSA regs in the "placeholder" block. Here, after
2081 * bitcode conversion is complete, we examine those placeholder definitions
2082 * and delete any with no references (which normally is all of them).
2083 *
2084 * If any definitions remain, we link the placeholder block into the
2085 * CFG. Otherwise, it is deleted.
2086 */
2087 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
2088 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
2089 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2090 DCHECK(inst != NULL);
2091 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2092 DCHECK(val != NULL);
2093 if (val->getNumUses() == 0) {
2094 inst->eraseFromParent();
2095 }
2096 }
2097 setDexOffset(cUnit, 0);
2098 if (cUnit->placeholderBB->empty()) {
2099 cUnit->placeholderBB->eraseFromParent();
2100 } else {
2101 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2102 cUnit->irb->CreateBr(cUnit->entryTargetBB);
2103 cUnit->entryTargetBB = cUnit->placeholderBB;
2104 }
2105 cUnit->irb->SetInsertPoint(cUnit->entryBB);
2106 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07002107
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002108 if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
2109 if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
2110 LOG(INFO) << "Bitcode verification FAILED for "
2111 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
2112 << " of size " << cUnit->insnsSize;
2113 cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
2114 }
2115 }
buzbee2cfc6392012-05-07 14:51:40 -07002116
buzbeead8f15e2012-06-18 14:49:45 -07002117 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
2118 // Write bitcode to file
2119 std::string errmsg;
2120 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
2121 oatReplaceSpecialChars(fname);
buzbee6459e7c2012-10-02 14:42:41 -07002122 // TODO: make configurable change naming mechanism to avoid fname length issues.
buzbee4f1181f2012-06-22 13:52:12 -07002123 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002124
buzbee6459e7c2012-10-02 14:42:41 -07002125 if (fname.size() > 240) {
2126 LOG(INFO) << "Warning: bitcode filename too long. Truncated.";
2127 fname.resize(240);
2128 }
2129
buzbeead8f15e2012-06-18 14:49:45 -07002130 llvm::OwningPtr<llvm::tool_output_file> out_file(
2131 new llvm::tool_output_file(fname.c_str(), errmsg,
2132 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002133
buzbeead8f15e2012-06-18 14:49:45 -07002134 if (!errmsg.empty()) {
2135 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2136 }
2137
2138 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2139 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002140 }
buzbee2cfc6392012-05-07 14:51:40 -07002141}
2142
2143RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2144 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002145 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002146 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2147 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002148 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002149 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002150 // FIXME: need to be more robust, handle FP and be in a position to
2151 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002152 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2153 memset(&res, 0, sizeof(res));
2154 res.location = kLocPhysReg;
2155 res.lowReg = oatAllocTemp(cUnit);
2156 res.home = true;
2157 res.sRegLow = INVALID_SREG;
2158 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002159 llvm::Type* ty = val->getType();
2160 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2161 (ty == cUnit->irb->getDoubleTy()));
2162 if (res.wide) {
2163 res.highReg = oatAllocTemp(cUnit);
2164 }
buzbee4f1181f2012-06-22 13:52:12 -07002165 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002166 } else {
2167 DCHECK_EQ(valName[0], 'v');
2168 int baseSReg = INVALID_SREG;
2169 sscanf(valName.c_str(), "v%d_", &baseSReg);
2170 res = cUnit->regLocation[baseSReg];
2171 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002172 }
2173 } else {
2174 res = it->second;
2175 }
2176 return res;
2177}
2178
2179Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2180{
2181 Instruction::Code res = Instruction::NOP;
2182 if (isWide) {
2183 switch(op) {
2184 case kOpAdd: res = Instruction::ADD_LONG; break;
2185 case kOpSub: res = Instruction::SUB_LONG; break;
2186 case kOpMul: res = Instruction::MUL_LONG; break;
2187 case kOpDiv: res = Instruction::DIV_LONG; break;
2188 case kOpRem: res = Instruction::REM_LONG; break;
2189 case kOpAnd: res = Instruction::AND_LONG; break;
2190 case kOpOr: res = Instruction::OR_LONG; break;
2191 case kOpXor: res = Instruction::XOR_LONG; break;
2192 case kOpLsl: res = Instruction::SHL_LONG; break;
2193 case kOpLsr: res = Instruction::USHR_LONG; break;
2194 case kOpAsr: res = Instruction::SHR_LONG; break;
2195 default: LOG(FATAL) << "Unexpected OpKind " << op;
2196 }
2197 } else if (isConst){
2198 switch(op) {
2199 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2200 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2201 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2202 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2203 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2204 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2205 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2206 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2207 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2208 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2209 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2210 default: LOG(FATAL) << "Unexpected OpKind " << op;
2211 }
2212 } else {
2213 switch(op) {
2214 case kOpAdd: res = Instruction::ADD_INT; break;
2215 case kOpSub: res = Instruction::SUB_INT; break;
2216 case kOpMul: res = Instruction::MUL_INT; break;
2217 case kOpDiv: res = Instruction::DIV_INT; break;
2218 case kOpRem: res = Instruction::REM_INT; break;
2219 case kOpAnd: res = Instruction::AND_INT; break;
2220 case kOpOr: res = Instruction::OR_INT; break;
2221 case kOpXor: res = Instruction::XOR_INT; break;
2222 case kOpLsl: res = Instruction::SHL_INT; break;
2223 case kOpLsr: res = Instruction::USHR_INT; break;
2224 case kOpAsr: res = Instruction::SHR_INT; break;
2225 default: LOG(FATAL) << "Unexpected OpKind " << op;
2226 }
2227 }
2228 return res;
2229}
2230
buzbee4f1181f2012-06-22 13:52:12 -07002231Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2232{
2233 Instruction::Code res = Instruction::NOP;
2234 if (isWide) {
2235 switch(op) {
2236 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2237 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2238 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2239 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2240 case kOpRem: res = Instruction::REM_DOUBLE; break;
2241 default: LOG(FATAL) << "Unexpected OpKind " << op;
2242 }
2243 } else {
2244 switch(op) {
2245 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2246 case kOpSub: res = Instruction::SUB_FLOAT; break;
2247 case kOpMul: res = Instruction::MUL_FLOAT; break;
2248 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2249 case kOpRem: res = Instruction::REM_FLOAT; break;
2250 default: LOG(FATAL) << "Unexpected OpKind " << op;
2251 }
2252 }
2253 return res;
2254}
2255
2256void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2257{
2258 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002259 /*
2260 * Normally, we won't ever generate an FP operation with an immediate
2261 * operand (not supported in Dex instruction set). However, the IR builder
2262 * may insert them - in particular for createNegFP. Recognize this case
2263 * and deal with it.
2264 */
2265 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2266 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2267 DCHECK(op2C == NULL);
2268 if ((op1C != NULL) && (op == kOpSub)) {
2269 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2270 if (rlDest.wide) {
2271 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2272 } else {
2273 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2274 }
buzbee4f1181f2012-06-22 13:52:12 -07002275 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002276 DCHECK(op1C == NULL);
2277 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2278 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2279 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2280 if (rlDest.wide) {
2281 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2282 } else {
2283 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2284 }
buzbee4f1181f2012-06-22 13:52:12 -07002285 }
2286}
2287
buzbee101305f2012-06-28 18:00:56 -07002288void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2289 Instruction::Code opcode)
2290{
2291 RegLocation rlDest = getLoc(cUnit, inst);
2292 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2293 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2294}
2295
buzbee76592632012-06-29 15:18:35 -07002296void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2297{
2298 RegLocation rlDest = getLoc(cUnit, inst);
2299 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2300 Instruction::Code opcode;
2301 if (rlDest.wide) {
2302 if (rlSrc.wide) {
2303 opcode = Instruction::LONG_TO_DOUBLE;
2304 } else {
2305 opcode = Instruction::INT_TO_DOUBLE;
2306 }
2307 } else {
2308 if (rlSrc.wide) {
2309 opcode = Instruction::LONG_TO_FLOAT;
2310 } else {
2311 opcode = Instruction::INT_TO_FLOAT;
2312 }
2313 }
2314 genConversion(cUnit, opcode, rlDest, rlSrc);
2315}
2316
TDYa1274ec8ccd2012-08-11 07:04:57 -07002317void cvtFPToInt(CompilationUnit* cUnit, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002318{
TDYa1274ec8ccd2012-08-11 07:04:57 -07002319 RegLocation rlDest = getLoc(cUnit, call_inst);
2320 RegLocation rlSrc = getLoc(cUnit, call_inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002321 Instruction::Code opcode;
2322 if (rlDest.wide) {
2323 if (rlSrc.wide) {
2324 opcode = Instruction::DOUBLE_TO_LONG;
2325 } else {
2326 opcode = Instruction::FLOAT_TO_LONG;
2327 }
2328 } else {
2329 if (rlSrc.wide) {
2330 opcode = Instruction::DOUBLE_TO_INT;
2331 } else {
2332 opcode = Instruction::FLOAT_TO_INT;
2333 }
2334 }
2335 genConversion(cUnit, opcode, rlDest, rlSrc);
2336}
2337
2338void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2339{
2340 RegLocation rlDest = getLoc(cUnit, inst);
2341 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2342 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2343}
2344
2345void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2346{
2347 RegLocation rlDest = getLoc(cUnit, inst);
2348 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2349 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2350 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2351 storeValue(cUnit, rlDest, rlSrc);
2352}
2353
2354void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2355{
2356 RegLocation rlDest = getLoc(cUnit, inst);
2357 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2358 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2359}
2360
2361
buzbee101305f2012-06-28 18:00:56 -07002362void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2363{
2364 // TODO: evaluate src/tgt types and add general support for more than int to long
2365 RegLocation rlDest = getLoc(cUnit, inst);
2366 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2367 DCHECK(rlDest.wide);
2368 DCHECK(!rlSrc.wide);
2369 DCHECK(!rlDest.fp);
2370 DCHECK(!rlSrc.fp);
2371 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2372 if (rlSrc.location == kLocPhysReg) {
2373 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2374 } else {
2375 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2376 }
2377 if (isSigned) {
2378 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2379 } else {
2380 loadConstant(cUnit, rlResult.highReg, 0);
2381 }
2382 storeValueWide(cUnit, rlDest, rlResult);
2383}
2384
buzbee2cfc6392012-05-07 14:51:40 -07002385void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2386{
2387 RegLocation rlDest = getLoc(cUnit, inst);
2388 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002389 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002390 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2391 if ((op == kOpSub) && (lhsImm != NULL)) {
2392 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002393 if (rlSrc1.wide) {
2394 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2395 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2396 } else {
2397 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2398 lhsImm->getSExtValue());
2399 }
buzbee4f1181f2012-06-22 13:52:12 -07002400 return;
2401 }
2402 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002403 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2404 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002405 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2406 if (!rlDest.wide && (constRhs != NULL)) {
buzbee2cfc6392012-05-07 14:51:40 -07002407 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
buzbee9a2487f2012-07-26 14:01:13 -07002408 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002409 } else {
2410 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002411 RegLocation rlSrc2;
2412 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002413 // ir_builder converts NOT_LONG to xor src, -1. Restore
2414 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2415 DCHECK_EQ(-1L, constRhs->getSExtValue());
2416 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002417 rlSrc2 = rlSrc1;
2418 } else {
2419 rlSrc2 = getLoc(cUnit, rhs);
2420 }
buzbee2cfc6392012-05-07 14:51:40 -07002421 if (rlDest.wide) {
2422 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2423 } else {
2424 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2425 }
2426 }
2427}
2428
buzbee2a83e8f2012-07-13 16:42:30 -07002429void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2430 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002431{
buzbee2a83e8f2012-07-13 16:42:30 -07002432 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2433 RegLocation rlDest = getLoc(cUnit, callInst);
2434 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2435 llvm::Value* rhs = callInst->getArgOperand(1);
2436 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2437 DCHECK(!rlDest.wide);
2438 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002439 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002440 RegLocation rlShift = getLoc(cUnit, rhs);
2441 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2442 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2443 } else {
2444 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2445 }
buzbee101305f2012-06-28 18:00:56 -07002446 }
2447}
2448
buzbee2cfc6392012-05-07 14:51:40 -07002449void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2450{
2451 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2452 DCHECK(brInst != NULL);
2453 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2454 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2455 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2456}
2457
2458void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2459{
2460 // Nop - these have already been processed
2461}
2462
2463void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2464{
2465 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2466 llvm::Value* retVal = retInst->getReturnValue();
2467 if (retVal != NULL) {
2468 RegLocation rlSrc = getLoc(cUnit, retVal);
2469 if (rlSrc.wide) {
2470 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2471 } else {
2472 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2473 }
2474 }
2475 genExitSequence(cUnit);
2476}
2477
2478ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2479{
2480 ConditionCode res = kCondAl;
2481 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002482 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002483 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2484 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2485 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002486 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002487 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002488 default: LOG(FATAL) << "Unexpected llvm condition";
2489 }
2490 return res;
2491}
2492
2493void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2494{
2495 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2496 UNIMPLEMENTED(FATAL);
2497}
2498
2499void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2500 llvm::BranchInst* brInst)
2501{
2502 // Get targets
2503 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2504 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2505 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2506 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2507 // Get comparison operands
2508 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2509 ConditionCode cond = getCond(iCmpInst->getPredicate());
2510 llvm::Value* lhs = iCmpInst->getOperand(0);
2511 // Not expecting a constant as 1st operand
2512 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2513 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2514 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2515 llvm::Value* rhs = inst->getOperand(1);
2516#if defined(TARGET_MIPS)
2517 // Compare and branch in one shot
2518 (void)taken;
2519 (void)cond;
2520 (void)rhs;
2521 UNIMPLEMENTED(FATAL);
2522#else
2523 //Compare, then branch
2524 // TODO: handle fused CMP_LONG/IF_xxZ case
2525 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2526 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002527 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2528 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002529 } else {
2530 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2531 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2532 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2533 }
2534 opCondBranch(cUnit, cond, taken);
2535#endif
2536 // Fallthrough
2537 opUnconditionalBranch(cUnit, fallThrough);
2538}
2539
2540void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2541 llvm::Function* callee)
2542{
2543 UNIMPLEMENTED(FATAL);
2544}
2545
buzbee2cfc6392012-05-07 14:51:40 -07002546void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2547{
buzbee4f1181f2012-06-22 13:52:12 -07002548 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002549 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2550 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002551 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2552 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002553 if (rlSrc.wide) {
2554 storeValueWide(cUnit, rlDest, rlSrc);
2555 } else {
2556 storeValue(cUnit, rlDest, rlSrc);
2557 }
2558}
2559
2560// Note: Immediate arg is a ConstantInt regardless of result type
2561void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2562{
buzbee4f1181f2012-06-22 13:52:12 -07002563 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002564 llvm::ConstantInt* src =
2565 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2566 uint64_t immval = src->getZExtValue();
2567 RegLocation rlDest = getLoc(cUnit, callInst);
2568 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2569 if (rlDest.wide) {
2570 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2571 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2572 storeValueWide(cUnit, rlDest, rlResult);
2573 } else {
2574 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2575 storeValue(cUnit, rlDest, rlResult);
2576 }
2577}
2578
buzbee101305f2012-06-28 18:00:56 -07002579void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2580 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002581{
buzbee4f1181f2012-06-22 13:52:12 -07002582 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002583 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002584 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002585 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002586 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002587 if (isString) {
2588 genConstString(cUnit, index, rlDest);
2589 } else {
2590 genConstClass(cUnit, index, rlDest);
2591 }
2592}
2593
2594void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2595{
2596 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2597 llvm::ConstantInt* offsetVal =
2598 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2599 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2600 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002601}
2602
buzbee4f1181f2012-06-22 13:52:12 -07002603void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2604{
buzbee32412962012-06-26 16:27:56 -07002605 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002606 llvm::ConstantInt* typeIdxVal =
2607 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2608 uint32_t typeIdx = typeIdxVal->getZExtValue();
2609 RegLocation rlDest = getLoc(cUnit, callInst);
2610 genNewInstance(cUnit, typeIdx, rlDest);
2611}
2612
buzbee8fa0fda2012-06-27 15:44:52 -07002613void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2614{
2615 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2616 llvm::ConstantInt* typeIdxVal =
2617 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2618 uint32_t typeIdx = typeIdxVal->getZExtValue();
2619 llvm::Value* len = callInst->getArgOperand(1);
2620 RegLocation rlLen = getLoc(cUnit, len);
2621 RegLocation rlDest = getLoc(cUnit, callInst);
2622 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2623}
2624
2625void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2626{
2627 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2628 llvm::ConstantInt* typeIdxVal =
2629 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2630 uint32_t typeIdx = typeIdxVal->getZExtValue();
2631 llvm::Value* src = callInst->getArgOperand(1);
2632 RegLocation rlSrc = getLoc(cUnit, src);
2633 RegLocation rlDest = getLoc(cUnit, callInst);
2634 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2635}
2636
buzbee32412962012-06-26 16:27:56 -07002637void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2638{
2639 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2640 llvm::Value* src = callInst->getArgOperand(0);
2641 RegLocation rlSrc = getLoc(cUnit, src);
2642 genThrow(cUnit, rlSrc);
2643}
2644
buzbee8fa0fda2012-06-27 15:44:52 -07002645void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2646 llvm::CallInst* callInst)
2647{
2648 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2649 llvm::ConstantInt* optFlags =
2650 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2651 llvm::Value* src = callInst->getArgOperand(1);
2652 RegLocation rlSrc = getLoc(cUnit, src);
2653 if (isEnter) {
2654 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2655 } else {
2656 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2657 }
2658}
2659
buzbee76592632012-06-29 15:18:35 -07002660void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002661{
2662 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2663 llvm::ConstantInt* optFlags =
2664 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2665 llvm::Value* src = callInst->getArgOperand(1);
2666 RegLocation rlSrc = getLoc(cUnit, src);
2667 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2668 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2669 RegLocation rlDest = getLoc(cUnit, callInst);
2670 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2671 int lenOffset = Array::LengthOffset().Int32Value();
2672 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2673 storeValue(cUnit, rlDest, rlResult);
2674}
2675
buzbee32412962012-06-26 16:27:56 -07002676void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2677{
buzbee32412962012-06-26 16:27:56 -07002678 RegLocation rlDest = getLoc(cUnit, callInst);
Ian Rogers474b6da2012-09-25 00:20:38 -07002679 genMoveException(cUnit, rlDest);
buzbee32412962012-06-26 16:27:56 -07002680}
2681
buzbee4f1181f2012-06-22 13:52:12 -07002682void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2683 bool isObject)
2684{
buzbee32412962012-06-26 16:27:56 -07002685 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002686 llvm::ConstantInt* typeIdxVal =
2687 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2688 uint32_t typeIdx = typeIdxVal->getZExtValue();
2689 RegLocation rlDest = getLoc(cUnit, callInst);
2690 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2691}
2692
buzbee8fa0fda2012-06-27 15:44:52 -07002693void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2694 bool isObject)
2695{
2696 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2697 llvm::ConstantInt* typeIdxVal =
2698 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2699 uint32_t typeIdx = typeIdxVal->getZExtValue();
2700 llvm::Value* src = callInst->getArgOperand(1);
2701 RegLocation rlSrc = getLoc(cUnit, src);
2702 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2703}
2704
2705void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2706 int scale)
2707{
2708 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2709 llvm::ConstantInt* optFlags =
2710 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2711 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2712 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2713 RegLocation rlDest = getLoc(cUnit, callInst);
2714 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2715 rlDest, scale);
2716}
2717
2718void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002719 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002720{
2721 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2722 llvm::ConstantInt* optFlags =
2723 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2724 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2725 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2726 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002727 if (isObject) {
2728 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2729 rlSrc, scale);
2730 } else {
2731 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2732 rlSrc, scale);
2733 }
2734}
2735
2736void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2737{
2738 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2739}
2740
2741void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2742 OpSize size, int scale)
2743{
2744 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002745}
2746
buzbee101305f2012-06-28 18:00:56 -07002747void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2748 bool isWide, bool isObj)
2749{
2750 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2751 llvm::ConstantInt* optFlags =
2752 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2753 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2754 llvm::ConstantInt* fieldIdx =
2755 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2756 RegLocation rlDest = getLoc(cUnit, callInst);
2757 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2758 size, rlDest, rlObj, isWide, isObj);
2759}
2760
2761void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2762 bool isWide, bool isObj)
2763{
2764 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2765 llvm::ConstantInt* optFlags =
2766 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2767 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2768 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2769 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002770 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002771 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2772 size, rlSrc, rlObj, isWide, isObj);
2773}
2774
2775void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2776{
2777 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2778 llvm::ConstantInt* typeIdx =
2779 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2780 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2781 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2782}
2783
buzbee76592632012-06-29 15:18:35 -07002784void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2785 Instruction::Code opcode)
2786{
2787 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2788 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2789 RegLocation rlDest = getLoc(cUnit, callInst);
2790 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2791}
2792
2793void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2794{
2795 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2796 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2797 RegLocation rlDest = getLoc(cUnit, callInst);
2798 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2799}
2800
buzbeef58c12c2012-07-03 15:06:29 -07002801void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2802{
2803 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2804 DCHECK(swInst != NULL);
2805 llvm::Value* testVal = swInst->getCondition();
2806 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2807 DCHECK(tableOffsetNode != NULL);
2808 llvm::ConstantInt* tableOffsetValue =
2809 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2810 int32_t tableOffset = tableOffsetValue->getSExtValue();
2811 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeea1da8a52012-07-09 14:00:21 -07002812 const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2813 u2 tableMagic = *table;
2814 if (tableMagic == 0x100) {
2815 genPackedSwitch(cUnit, tableOffset, rlSrc);
2816 } else {
2817 DCHECK_EQ(tableMagic, 0x200);
2818 genSparseSwitch(cUnit, tableOffset, rlSrc);
2819 }
buzbeef58c12c2012-07-03 15:06:29 -07002820}
2821
buzbee6969d502012-06-15 16:40:31 -07002822void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002823 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002824{
2825 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2826 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002827 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002828 info->result.location = kLocInvalid;
2829 } else {
2830 info->result = getLoc(cUnit, callInst);
2831 }
2832 llvm::ConstantInt* invokeTypeVal =
2833 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2834 llvm::ConstantInt* methodIndexVal =
2835 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2836 llvm::ConstantInt* optFlagsVal =
2837 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2838 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2839 info->index = methodIndexVal->getZExtValue();
2840 info->optFlags = optFlagsVal->getZExtValue();
2841 info->offset = cUnit->currentDalvikOffset;
2842
buzbee6969d502012-06-15 16:40:31 -07002843 // Count the argument words, and then build argument array.
2844 info->numArgWords = 0;
2845 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2846 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2847 info->numArgWords += tLoc.wide ? 2 : 1;
2848 }
2849 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2850 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2851 // Now, fill in the location records, synthesizing high loc of wide vals
2852 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002853 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002854 if (info->args[next].wide) {
2855 next++;
2856 // TODO: Might make sense to mark this as an invalid loc
2857 info->args[next].origSReg = info->args[next-1].origSReg+1;
2858 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2859 }
2860 next++;
2861 }
buzbee4f4dfc72012-07-02 14:54:44 -07002862 // TODO - rework such that we no longer need isRange
2863 info->isRange = (info->numArgWords > 5);
2864
buzbee76592632012-06-29 15:18:35 -07002865 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002866 genFilledNewArray(cUnit, info);
2867 } else {
2868 genInvoke(cUnit, info);
2869 }
buzbee6969d502012-06-15 16:40:31 -07002870}
2871
buzbeead8f15e2012-06-18 14:49:45 -07002872/* Look up the RegLocation associated with a Value. Must already be defined */
2873RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2874{
2875 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2876 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2877 return it->second;
2878}
2879
buzbee2cfc6392012-05-07 14:51:40 -07002880bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2881{
buzbee0967a252012-09-14 10:43:54 -07002882 while (cUnit->llvmBlocks.find(bb) == cUnit->llvmBlocks.end()) {
2883 llvm::BasicBlock* nextBB = NULL;
2884 cUnit->llvmBlocks.insert(bb);
2885 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2886 // Define the starting label
2887 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2888 // Extract the type and starting offset from the block's name
buzbee951c0a12012-10-03 16:31:39 -07002889 char blockType = kInvalidBlock;
2890 if (isEntry) {
2891 blockType = kNormalBlock;
2892 blockLabel->operands[0] = 0;
2893 } else if (!bb->hasName()) {
2894 blockType = kNormalBlock;
2895 blockLabel->operands[0] = DexFile::kDexNoIndex;
buzbee0967a252012-09-14 10:43:54 -07002896 } else {
buzbee951c0a12012-10-03 16:31:39 -07002897 std::string blockName = bb->getName().str();
2898 int dummy;
2899 sscanf(blockName.c_str(), kLabelFormat, &blockType, &blockLabel->operands[0], &dummy);
2900 cUnit->currentDalvikOffset = blockLabel->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002901 }
buzbee951c0a12012-10-03 16:31:39 -07002902 DCHECK((blockType == kNormalBlock) || (blockType == kCatchBlock));
2903 cUnit->currentDalvikOffset = blockLabel->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002904 // Set the label kind
2905 blockLabel->opcode = kPseudoNormalBlockLabel;
2906 // Insert the label
2907 oatAppendLIR(cUnit, blockLabel);
buzbee2cfc6392012-05-07 14:51:40 -07002908
buzbee0967a252012-09-14 10:43:54 -07002909 LIR* headLIR = NULL;
buzbee8320f382012-09-11 16:29:42 -07002910
buzbee0967a252012-09-14 10:43:54 -07002911 if (blockType == kCatchBlock) {
Bill Buzbeea5b30242012-09-28 07:19:44 -07002912 headLIR = newLIR0(cUnit, kPseudoExportedPC);
buzbee0967a252012-09-14 10:43:54 -07002913 }
buzbee8320f382012-09-11 16:29:42 -07002914
buzbee0967a252012-09-14 10:43:54 -07002915 // Free temp registers and reset redundant store tracking */
2916 oatResetRegPool(cUnit);
2917 oatResetDefTracking(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002918
buzbee0967a252012-09-14 10:43:54 -07002919 //TODO: restore oat incoming liveness optimization
2920 oatClobberAllRegs(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002921
buzbee0967a252012-09-14 10:43:54 -07002922 if (isEntry) {
2923 RegLocation* argLocs = (RegLocation*)
2924 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2925 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2926 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2927 // Skip past Method*
2928 it++;
2929 for (unsigned i = 0; it != it_end; ++it) {
2930 llvm::Value* val = it;
2931 argLocs[i++] = valToLoc(cUnit, val);
2932 llvm::Type* ty = val->getType();
2933 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2934 argLocs[i] = argLocs[i-1];
2935 argLocs[i].lowReg = argLocs[i].highReg;
2936 argLocs[i].origSReg++;
2937 argLocs[i].sRegLow = INVALID_SREG;
2938 argLocs[i].highWord = true;
2939 i++;
2940 }
2941 }
2942 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
2943 }
2944
2945 // Visit all of the instructions in the block
2946 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2947 llvm::Instruction* inst = it;
2948 llvm::BasicBlock::iterator nextIt = ++it;
2949 // Extract the Dalvik offset from the instruction
2950 uint32_t opcode = inst->getOpcode();
2951 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2952 if (dexOffsetNode != NULL) {
2953 llvm::ConstantInt* dexOffsetValue =
2954 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2955 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2956 }
2957
2958 oatResetRegPool(cUnit);
2959 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2960 oatClobberAllRegs(cUnit);
2961 }
2962
2963 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2964 oatResetDefTracking(cUnit);
2965 }
2966
2967 #ifndef NDEBUG
2968 /* Reset temp tracking sanity check */
2969 cUnit->liveSReg = INVALID_SREG;
2970 #endif
2971
2972 // TODO: use llvm opcode name here instead of "boundary" if verbose
2973 LIR* boundaryLIR = markBoundary(cUnit, cUnit->currentDalvikOffset, "boundary");
2974
2975 /* Remember the first LIR for thisl block*/
2976 if (headLIR == NULL) {
2977 headLIR = boundaryLIR;
2978 headLIR->defMask = ENCODE_ALL;
2979 }
2980
2981 switch(opcode) {
2982
2983 case llvm::Instruction::ICmp: {
2984 llvm::Instruction* nextInst = nextIt;
2985 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2986 if (brInst != NULL /* and... */) {
2987 cvtICmpBr(cUnit, inst, brInst);
2988 ++it;
2989 } else {
2990 cvtICmp(cUnit, inst);
2991 }
2992 }
2993 break;
2994
2995 case llvm::Instruction::Call: {
2996 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2997 llvm::Function* callee = callInst->getCalledFunction();
2998 greenland::IntrinsicHelper::IntrinsicId id =
2999 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3000 switch (id) {
3001 case greenland::IntrinsicHelper::AllocaShadowFrame:
3002 case greenland::IntrinsicHelper::SetShadowFrameEntry:
3003 case greenland::IntrinsicHelper::PopShadowFrame:
3004 // Ignore shadow frame stuff for quick compiler
3005 break;
3006 case greenland::IntrinsicHelper::CopyInt:
3007 case greenland::IntrinsicHelper::CopyObj:
3008 case greenland::IntrinsicHelper::CopyFloat:
3009 case greenland::IntrinsicHelper::CopyLong:
3010 case greenland::IntrinsicHelper::CopyDouble:
3011 cvtCopy(cUnit, callInst);
3012 break;
3013 case greenland::IntrinsicHelper::ConstInt:
3014 case greenland::IntrinsicHelper::ConstObj:
3015 case greenland::IntrinsicHelper::ConstLong:
3016 case greenland::IntrinsicHelper::ConstFloat:
3017 case greenland::IntrinsicHelper::ConstDouble:
3018 cvtConst(cUnit, callInst);
3019 break;
3020 case greenland::IntrinsicHelper::DivInt:
3021 case greenland::IntrinsicHelper::DivLong:
3022 cvtBinOp(cUnit, kOpDiv, inst);
3023 break;
3024 case greenland::IntrinsicHelper::RemInt:
3025 case greenland::IntrinsicHelper::RemLong:
3026 cvtBinOp(cUnit, kOpRem, inst);
3027 break;
3028 case greenland::IntrinsicHelper::MethodInfo:
3029 // Already dealt with - just ignore it here.
3030 break;
3031 case greenland::IntrinsicHelper::CheckSuspend:
3032 genSuspendTest(cUnit, 0 /* optFlags already applied */);
3033 break;
3034 case greenland::IntrinsicHelper::HLInvokeObj:
3035 case greenland::IntrinsicHelper::HLInvokeFloat:
3036 case greenland::IntrinsicHelper::HLInvokeDouble:
3037 case greenland::IntrinsicHelper::HLInvokeLong:
3038 case greenland::IntrinsicHelper::HLInvokeInt:
3039 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
3040 break;
3041 case greenland::IntrinsicHelper::HLInvokeVoid:
3042 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
3043 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003044 case greenland::IntrinsicHelper::HLFilledNewArray:
buzbee0967a252012-09-14 10:43:54 -07003045 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
3046 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003047 case greenland::IntrinsicHelper::HLFillArrayData:
buzbee0967a252012-09-14 10:43:54 -07003048 cvtFillArrayData(cUnit, callInst);
3049 break;
3050 case greenland::IntrinsicHelper::ConstString:
3051 cvtConstObject(cUnit, callInst, true /* isString */);
3052 break;
3053 case greenland::IntrinsicHelper::ConstClass:
3054 cvtConstObject(cUnit, callInst, false /* isString */);
3055 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003056 case greenland::IntrinsicHelper::HLCheckCast:
buzbee0967a252012-09-14 10:43:54 -07003057 cvtCheckCast(cUnit, callInst);
3058 break;
3059 case greenland::IntrinsicHelper::NewInstance:
3060 cvtNewInstance(cUnit, callInst);
3061 break;
3062 case greenland::IntrinsicHelper::HLSgetObject:
3063 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
3064 break;
3065 case greenland::IntrinsicHelper::HLSget:
3066 case greenland::IntrinsicHelper::HLSgetFloat:
3067 case greenland::IntrinsicHelper::HLSgetBoolean:
3068 case greenland::IntrinsicHelper::HLSgetByte:
3069 case greenland::IntrinsicHelper::HLSgetChar:
3070 case greenland::IntrinsicHelper::HLSgetShort:
3071 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
3072 break;
3073 case greenland::IntrinsicHelper::HLSgetWide:
3074 case greenland::IntrinsicHelper::HLSgetDouble:
3075 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
3076 break;
3077 case greenland::IntrinsicHelper::HLSput:
3078 case greenland::IntrinsicHelper::HLSputFloat:
3079 case greenland::IntrinsicHelper::HLSputBoolean:
3080 case greenland::IntrinsicHelper::HLSputByte:
3081 case greenland::IntrinsicHelper::HLSputChar:
3082 case greenland::IntrinsicHelper::HLSputShort:
3083 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
3084 break;
3085 case greenland::IntrinsicHelper::HLSputWide:
3086 case greenland::IntrinsicHelper::HLSputDouble:
3087 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
3088 break;
3089 case greenland::IntrinsicHelper::HLSputObject:
3090 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
3091 break;
3092 case greenland::IntrinsicHelper::GetException:
3093 cvtMoveException(cUnit, callInst);
3094 break;
TDYa127f71bf5a2012-07-29 20:09:52 -07003095 case greenland::IntrinsicHelper::HLThrowException:
buzbee0967a252012-09-14 10:43:54 -07003096 cvtThrow(cUnit, callInst);
3097 break;
3098 case greenland::IntrinsicHelper::MonitorEnter:
3099 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
3100 break;
3101 case greenland::IntrinsicHelper::MonitorExit:
3102 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
3103 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003104 case greenland::IntrinsicHelper::OptArrayLength:
buzbee0967a252012-09-14 10:43:54 -07003105 cvtArrayLength(cUnit, callInst);
3106 break;
3107 case greenland::IntrinsicHelper::NewArray:
3108 cvtNewArray(cUnit, callInst);
3109 break;
3110 case greenland::IntrinsicHelper::InstanceOf:
3111 cvtInstanceOf(cUnit, callInst);
3112 break;
3113
3114 case greenland::IntrinsicHelper::HLArrayGet:
3115 case greenland::IntrinsicHelper::HLArrayGetObject:
3116 case greenland::IntrinsicHelper::HLArrayGetFloat:
3117 cvtAget(cUnit, callInst, kWord, 2);
3118 break;
3119 case greenland::IntrinsicHelper::HLArrayGetWide:
3120 case greenland::IntrinsicHelper::HLArrayGetDouble:
3121 cvtAget(cUnit, callInst, kLong, 3);
3122 break;
3123 case greenland::IntrinsicHelper::HLArrayGetBoolean:
3124 cvtAget(cUnit, callInst, kUnsignedByte, 0);
3125 break;
3126 case greenland::IntrinsicHelper::HLArrayGetByte:
3127 cvtAget(cUnit, callInst, kSignedByte, 0);
3128 break;
3129 case greenland::IntrinsicHelper::HLArrayGetChar:
3130 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
3131 break;
3132 case greenland::IntrinsicHelper::HLArrayGetShort:
3133 cvtAget(cUnit, callInst, kSignedHalf, 1);
3134 break;
3135
3136 case greenland::IntrinsicHelper::HLArrayPut:
3137 case greenland::IntrinsicHelper::HLArrayPutFloat:
3138 cvtAputPrimitive(cUnit, callInst, kWord, 2);
3139 break;
3140 case greenland::IntrinsicHelper::HLArrayPutObject:
3141 cvtAputObj(cUnit, callInst);
3142 break;
3143 case greenland::IntrinsicHelper::HLArrayPutWide:
3144 case greenland::IntrinsicHelper::HLArrayPutDouble:
3145 cvtAputPrimitive(cUnit, callInst, kLong, 3);
3146 break;
3147 case greenland::IntrinsicHelper::HLArrayPutBoolean:
3148 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
3149 break;
3150 case greenland::IntrinsicHelper::HLArrayPutByte:
3151 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
3152 break;
3153 case greenland::IntrinsicHelper::HLArrayPutChar:
3154 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
3155 break;
3156 case greenland::IntrinsicHelper::HLArrayPutShort:
3157 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
3158 break;
3159
3160 case greenland::IntrinsicHelper::HLIGet:
3161 case greenland::IntrinsicHelper::HLIGetFloat:
3162 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3163 break;
3164 case greenland::IntrinsicHelper::HLIGetObject:
3165 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3166 break;
3167 case greenland::IntrinsicHelper::HLIGetWide:
3168 case greenland::IntrinsicHelper::HLIGetDouble:
3169 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3170 break;
3171 case greenland::IntrinsicHelper::HLIGetBoolean:
3172 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3173 false /* obj */);
3174 break;
3175 case greenland::IntrinsicHelper::HLIGetByte:
3176 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3177 false /* obj */);
3178 break;
3179 case greenland::IntrinsicHelper::HLIGetChar:
3180 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3181 false /* obj */);
3182 break;
3183 case greenland::IntrinsicHelper::HLIGetShort:
3184 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3185 false /* obj */);
3186 break;
3187
3188 case greenland::IntrinsicHelper::HLIPut:
3189 case greenland::IntrinsicHelper::HLIPutFloat:
3190 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3191 break;
3192 case greenland::IntrinsicHelper::HLIPutObject:
3193 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3194 break;
3195 case greenland::IntrinsicHelper::HLIPutWide:
3196 case greenland::IntrinsicHelper::HLIPutDouble:
3197 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3198 break;
3199 case greenland::IntrinsicHelper::HLIPutBoolean:
3200 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3201 false /* obj */);
3202 break;
3203 case greenland::IntrinsicHelper::HLIPutByte:
3204 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3205 false /* obj */);
3206 break;
3207 case greenland::IntrinsicHelper::HLIPutChar:
3208 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3209 false /* obj */);
3210 break;
3211 case greenland::IntrinsicHelper::HLIPutShort:
3212 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3213 false /* obj */);
3214 break;
3215
3216 case greenland::IntrinsicHelper::IntToChar:
3217 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3218 break;
3219 case greenland::IntrinsicHelper::IntToShort:
3220 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3221 break;
3222 case greenland::IntrinsicHelper::IntToByte:
3223 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3224 break;
3225
TDYa1274ec8ccd2012-08-11 07:04:57 -07003226 case greenland::IntrinsicHelper::F2I:
3227 case greenland::IntrinsicHelper::D2I:
3228 case greenland::IntrinsicHelper::F2L:
3229 case greenland::IntrinsicHelper::D2L:
3230 cvtFPToInt(cUnit, callInst);
3231 break;
3232
buzbee0967a252012-09-14 10:43:54 -07003233 case greenland::IntrinsicHelper::CmplFloat:
3234 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3235 break;
3236 case greenland::IntrinsicHelper::CmpgFloat:
3237 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3238 break;
3239 case greenland::IntrinsicHelper::CmplDouble:
3240 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3241 break;
3242 case greenland::IntrinsicHelper::CmpgDouble:
3243 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3244 break;
3245
3246 case greenland::IntrinsicHelper::CmpLong:
3247 cvtLongCompare(cUnit, callInst);
3248 break;
3249
3250 case greenland::IntrinsicHelper::SHLLong:
3251 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
3252 break;
3253 case greenland::IntrinsicHelper::SHRLong:
3254 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3255 break;
3256 case greenland::IntrinsicHelper::USHRLong:
3257 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3258 break;
3259 case greenland::IntrinsicHelper::SHLInt:
3260 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3261 break;
3262 case greenland::IntrinsicHelper::SHRInt:
3263 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3264 break;
3265 case greenland::IntrinsicHelper::USHRInt:
3266 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3267 break;
3268
3269 case greenland::IntrinsicHelper::CatchTargets: {
3270 llvm::SwitchInst* swInst =
3271 llvm::dyn_cast<llvm::SwitchInst>(nextIt);
3272 DCHECK(swInst != NULL);
3273 /*
3274 * Discard the edges and the following conditional branch.
3275 * Do a direct branch to the default target (which is the
3276 * "work" portion of the pair.
3277 * TODO: awful code layout - rework
3278 */
3279 llvm::BasicBlock* targetBB = swInst->getDefaultDest();
3280 DCHECK(targetBB != NULL);
3281 opUnconditionalBranch(cUnit,
3282 cUnit->blockToLabelMap.Get(targetBB));
3283 ++it;
3284 // Set next bb to default target - improves code layout
3285 nextBB = targetBB;
3286 }
3287 break;
3288
3289 default:
3290 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3291 << cUnit->intrinsic_helper->GetName(id);
3292 }
3293 }
3294 break;
3295
3296 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3297 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3298 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3299 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3300 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3301 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3302 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3303 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3304 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
3305 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3306 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
3307 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3308 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3309 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3310 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3311 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
3312 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003313 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3314 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3315 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
3316
3317 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3318 break;
3319 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3320 break;
3321
3322 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3323
3324 case llvm::Instruction::Unreachable:
3325 break; // FIXME: can we really ignore these?
3326
3327 case llvm::Instruction::Shl:
3328 case llvm::Instruction::LShr:
3329 case llvm::Instruction::AShr:
3330 case llvm::Instruction::Invoke:
3331 case llvm::Instruction::FPToUI:
TDYa1274ec8ccd2012-08-11 07:04:57 -07003332 case llvm::Instruction::FPToSI:
buzbee0967a252012-09-14 10:43:54 -07003333 case llvm::Instruction::UIToFP:
3334 case llvm::Instruction::PtrToInt:
3335 case llvm::Instruction::IntToPtr:
3336 case llvm::Instruction::FCmp:
3337 case llvm::Instruction::URem:
3338 case llvm::Instruction::UDiv:
3339 case llvm::Instruction::Resume:
3340 case llvm::Instruction::Alloca:
3341 case llvm::Instruction::GetElementPtr:
3342 case llvm::Instruction::Fence:
3343 case llvm::Instruction::AtomicCmpXchg:
3344 case llvm::Instruction::AtomicRMW:
3345 case llvm::Instruction::BitCast:
3346 case llvm::Instruction::VAArg:
3347 case llvm::Instruction::Select:
3348 case llvm::Instruction::UserOp1:
3349 case llvm::Instruction::UserOp2:
3350 case llvm::Instruction::ExtractElement:
3351 case llvm::Instruction::InsertElement:
3352 case llvm::Instruction::ShuffleVector:
3353 case llvm::Instruction::ExtractValue:
3354 case llvm::Instruction::InsertValue:
3355 case llvm::Instruction::LandingPad:
3356 case llvm::Instruction::IndirectBr:
3357 case llvm::Instruction::Load:
3358 case llvm::Instruction::Store:
3359 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3360
3361 default:
3362 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3363 break;
buzbeead8f15e2012-06-18 14:49:45 -07003364 }
3365 }
buzbee2cfc6392012-05-07 14:51:40 -07003366
buzbee0967a252012-09-14 10:43:54 -07003367 if (headLIR != NULL) {
3368 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
buzbee2cfc6392012-05-07 14:51:40 -07003369 }
buzbee0967a252012-09-14 10:43:54 -07003370 if (nextBB != NULL) {
3371 bb = nextBB;
3372 nextBB = NULL;
buzbee6969d502012-06-15 16:40:31 -07003373 }
buzbee6969d502012-06-15 16:40:31 -07003374 }
buzbee2cfc6392012-05-07 14:51:40 -07003375 return false;
3376}
3377
3378/*
3379 * Convert LLVM_IR to MIR:
3380 * o Iterate through the LLVM_IR and construct a graph using
3381 * standard MIR building blocks.
3382 * o Perform a basic-block optimization pass to remove unnecessary
3383 * store/load sequences.
3384 * o Convert the LLVM Value operands into RegLocations where applicable.
3385 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3386 * o Perform register promotion
3387 * o Iterate through the graph a basic block at a time, generating
3388 * LIR.
3389 * o Assemble LIR as usual.
3390 * o Profit.
3391 */
3392void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3393{
buzbeead8f15e2012-06-18 14:49:45 -07003394 llvm::Function* func = cUnit->func;
3395 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003396 // Allocate a list for LIR basic block labels
3397 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07003398 (LIR*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3399 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003400 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003401 for (llvm::Function::iterator i = func->begin(),
3402 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003403 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3404 &labelList[nextLabel++]);
3405 }
buzbeead8f15e2012-06-18 14:49:45 -07003406
3407 /*
3408 * Keep honest - clear regLocations, Value => RegLocation,
3409 * promotion map and VmapTables.
3410 */
3411 cUnit->locMap.clear(); // Start fresh
3412 cUnit->regLocation = NULL;
3413 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3414 i++) {
3415 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3416 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3417 }
3418 cUnit->coreSpillMask = 0;
3419 cUnit->numCoreSpills = 0;
3420 cUnit->fpSpillMask = 0;
3421 cUnit->numFPSpills = 0;
3422 cUnit->coreVmapTable.clear();
3423 cUnit->fpVmapTable.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003424
3425 /*
3426 * At this point, we've lost all knowledge of register promotion.
3427 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003428 * exists - not required for correctness). Normally, this will
3429 * be the first instruction we encounter, so we won't have to iterate
3430 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003431 */
buzbeeca7a5e42012-08-20 11:12:18 -07003432 for (llvm::inst_iterator i = llvm::inst_begin(func),
3433 e = llvm::inst_end(func); i != e; ++i) {
3434 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(&*i);
3435 if (callInst != NULL) {
3436 llvm::Function* callee = callInst->getCalledFunction();
3437 greenland::IntrinsicHelper::IntrinsicId id =
3438 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3439 if (id == greenland::IntrinsicHelper::MethodInfo) {
3440 if (cUnit->printMe) {
3441 LOG(INFO) << "Found MethodInfo";
3442 }
3443 llvm::MDNode* regInfoNode = callInst->getMetadata("RegInfo");
3444 if (regInfoNode != NULL) {
3445 llvm::ConstantInt* numInsValue =
3446 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(0));
3447 llvm::ConstantInt* numRegsValue =
3448 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(1));
3449 llvm::ConstantInt* numOutsValue =
3450 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(2));
3451 llvm::ConstantInt* numCompilerTempsValue =
3452 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(3));
3453 llvm::ConstantInt* numSSARegsValue =
3454 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(4));
3455 if (cUnit->printMe) {
3456 LOG(INFO) << "RegInfo - Ins:" << numInsValue->getZExtValue()
3457 << ", Regs:" << numRegsValue->getZExtValue()
3458 << ", Outs:" << numOutsValue->getZExtValue()
3459 << ", CTemps:" << numCompilerTempsValue->getZExtValue()
3460 << ", SSARegs:" << numSSARegsValue->getZExtValue();
3461 }
3462 }
3463 llvm::MDNode* pmapInfoNode = callInst->getMetadata("PromotionMap");
3464 if (pmapInfoNode != NULL) {
3465 int elems = pmapInfoNode->getNumOperands();
3466 if (cUnit->printMe) {
3467 LOG(INFO) << "PMap size: " << elems;
3468 }
3469 for (int i = 0; i < elems; i++) {
3470 llvm::ConstantInt* rawMapData =
3471 static_cast<llvm::ConstantInt*>(pmapInfoNode->getOperand(i));
3472 uint32_t mapData = rawMapData->getZExtValue();
3473 PromotionMap* p = &cUnit->promotionMap[i];
3474 p->firstInPair = (mapData >> 24) & 0xff;
3475 p->fpReg = (mapData >> 16) & 0xff;
3476 p->coreReg = (mapData >> 8) & 0xff;
3477 p->fpLocation = static_cast<RegLocationType>((mapData >> 4) & 0xf);
3478 if (p->fpLocation == kLocPhysReg) {
3479 oatRecordFpPromotion(cUnit, p->fpReg, i);
3480 }
3481 p->coreLocation = static_cast<RegLocationType>(mapData & 0xf);
3482 if (p->coreLocation == kLocPhysReg) {
3483 oatRecordCorePromotion(cUnit, p->coreReg, i);
3484 }
3485 }
3486 if (cUnit->printMe) {
3487 oatDumpPromotionMap(cUnit);
3488 }
3489 }
3490 break;
3491 }
3492 }
3493 }
3494 oatAdjustSpillMask(cUnit);
3495 cUnit->frameSize = oatComputeFrameSize(cUnit);
buzbeead8f15e2012-06-18 14:49:45 -07003496
3497 // Create RegLocations for arguments
3498 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3499 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3500 for (; it != it_end; ++it) {
3501 llvm::Value* val = it;
3502 createLocFromValue(cUnit, val);
3503 }
3504 // Create RegLocations for all non-argument defintions
3505 for (llvm::inst_iterator i = llvm::inst_begin(func),
3506 e = llvm::inst_end(func); i != e; ++i) {
3507 llvm::Value* val = &*i;
3508 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3509 createLocFromValue(cUnit, val);
3510 }
3511 }
3512
buzbee2cfc6392012-05-07 14:51:40 -07003513 // Walk the blocks, generating code.
3514 for (llvm::Function::iterator i = cUnit->func->begin(),
3515 e = cUnit->func->end(); i != e; ++i) {
3516 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3517 }
3518
3519 handleSuspendLaunchpads(cUnit);
3520
3521 handleThrowLaunchpads(cUnit);
3522
3523 handleIntrinsicLaunchpads(cUnit);
3524
buzbee692be802012-08-29 15:52:59 -07003525 cUnit->func->eraseFromParent();
3526 cUnit->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003527}
3528
3529
3530} // namespace art
3531
3532#endif // ART_USE_QUICK_COMPILER