blob: 31fc9cf29ef616c0775fd7fe8fe862ec4b3c9d10 [file] [log] [blame]
buzbee2cfc6392012-05-07 14:51:40 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#if defined(ART_USE_QUICK_COMPILER)
18
19#include "object_utils.h"
20
21#include <llvm/Support/ToolOutputFile.h>
22#include <llvm/Bitcode/ReaderWriter.h>
23#include <llvm/Analysis/Verifier.h>
24#include <llvm/Metadata.h>
25#include <llvm/ADT/DepthFirstIterator.h>
26#include <llvm/Instruction.h>
27#include <llvm/Type.h>
28#include <llvm/Instructions.h>
29#include <llvm/Support/Casting.h>
buzbeead8f15e2012-06-18 14:49:45 -070030#include <llvm/Support/InstIterator.h>
buzbee2cfc6392012-05-07 14:51:40 -070031
buzbee8320f382012-09-11 16:29:42 -070032static const char* kLabelFormat = "%c0x%x_%d";
33static const char kNormalBlock = 'L';
34static const char kCatchBlock = 'C';
buzbee2cfc6392012-05-07 14:51:40 -070035
36namespace art {
37extern const RegLocation badLoc;
buzbeeb03f4872012-06-11 15:22:11 -070038RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070039
40llvm::BasicBlock* getLLVMBlock(CompilationUnit* cUnit, int id)
41{
42 return cUnit->idToBlockMap.Get(id);
43}
44
45llvm::Value* getLLVMValue(CompilationUnit* cUnit, int sReg)
46{
47 return (llvm::Value*)oatGrowableListGetElement(&cUnit->llvmValues, sReg);
48}
49
50// Replace the placeholder value with the real definition
51void defineValue(CompilationUnit* cUnit, llvm::Value* val, int sReg)
52{
53 llvm::Value* placeholder = getLLVMValue(cUnit, sReg);
buzbee9a2487f2012-07-26 14:01:13 -070054 if (placeholder == NULL) {
55 // This can happen on instruction rewrite on verification failure
Bill Buzbeec9f40dd2012-08-15 11:35:25 -070056 LOG(WARNING) << "Null placeholder";
buzbee9a2487f2012-07-26 14:01:13 -070057 return;
58 }
buzbee2cfc6392012-05-07 14:51:40 -070059 placeholder->replaceAllUsesWith(val);
60 val->takeName(placeholder);
61 cUnit->llvmValues.elemList[sReg] = (intptr_t)val;
buzbee4be777b2012-07-12 14:38:18 -070062 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
63 DCHECK(inst != NULL);
64 inst->eraseFromParent();
buzbee2cfc6392012-05-07 14:51:40 -070065}
66
67llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
68{
69 llvm::Type* res = NULL;
70 if (loc.wide) {
71 if (loc.fp)
buzbee4f1181f2012-06-22 13:52:12 -070072 res = cUnit->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070073 else
buzbee4f1181f2012-06-22 13:52:12 -070074 res = cUnit->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070075 } else {
76 if (loc.fp) {
buzbee4f1181f2012-06-22 13:52:12 -070077 res = cUnit->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070078 } else {
79 if (loc.ref)
80 res = cUnit->irb->GetJObjectTy();
81 else
buzbee4f1181f2012-06-22 13:52:12 -070082 res = cUnit->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -070083 }
84 }
85 return res;
86}
87
buzbeead8f15e2012-06-18 14:49:45 -070088/* Create an in-memory RegLocation from an llvm Value. */
89void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
90{
91 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
92 std::string s(val->getName().str());
93 const char* valName = s.c_str();
buzbeead8f15e2012-06-18 14:49:45 -070094 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
95 DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
96 int baseSReg = INVALID_SREG;
97 int subscript = -1;
98 sscanf(valName, "v%d_%d", &baseSReg, &subscript);
99 if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
100 baseSReg = SSA_METHOD_BASEREG;
101 subscript = 0;
102 }
buzbeead8f15e2012-06-18 14:49:45 -0700103 DCHECK_NE(baseSReg, INVALID_SREG);
104 DCHECK_NE(subscript, -1);
105 // TODO: redo during C++'ification
106 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
107 INVALID_REG, INVALID_SREG, INVALID_SREG};
108 llvm::Type* ty = val->getType();
109 loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
110 (ty == cUnit->irb->getDoubleTy()));
111 loc.defined = true;
buzbeeca7a5e42012-08-20 11:12:18 -0700112 loc.home = false; // May change during promotion
buzbeead8f15e2012-06-18 14:49:45 -0700113 loc.sRegLow = baseSReg;
114 loc.origSReg = cUnit->locMap.size();
buzbeeca7a5e42012-08-20 11:12:18 -0700115 PromotionMap pMap = cUnit->promotionMap[baseSReg];
116 if (ty == cUnit->irb->getFloatTy()) {
117 loc.fp = true;
118 if (pMap.fpLocation == kLocPhysReg) {
119 loc.lowReg = pMap.fpReg;
120 loc.location = kLocPhysReg;
121 loc.home = true;
122 }
123 } else if (ty == cUnit->irb->getDoubleTy()) {
124 loc.fp = true;
125 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
126 if ((pMap.fpLocation == kLocPhysReg) &&
127 (pMapHigh.fpLocation == kLocPhysReg) &&
128 ((pMap.fpReg & 0x1) == 0) &&
129 (pMap.fpReg + 1 == pMapHigh.fpReg)) {
130 loc.lowReg = pMap.fpReg;
131 loc.highReg = pMapHigh.fpReg;
132 loc.location = kLocPhysReg;
133 loc.home = true;
134 }
135 } else if (ty == cUnit->irb->GetJObjectTy()) {
136 loc.ref = true;
137 if (pMap.coreLocation == kLocPhysReg) {
138 loc.lowReg = pMap.coreReg;
139 loc.location = kLocPhysReg;
140 loc.home = true;
141 }
142 } else if (ty == cUnit->irb->getInt64Ty()) {
143 loc.core = true;
144 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
145 if ((pMap.coreLocation == kLocPhysReg) &&
146 (pMapHigh.coreLocation == kLocPhysReg)) {
147 loc.lowReg = pMap.coreReg;
148 loc.highReg = pMapHigh.coreReg;
149 loc.location = kLocPhysReg;
150 loc.home = true;
151 }
152 } else {
153 loc.core = true;
154 if (pMap.coreLocation == kLocPhysReg) {
155 loc.lowReg = pMap.coreReg;
156 loc.location = kLocPhysReg;
157 loc.home = true;
158 }
159 }
160
161 if (cUnit->printMe && loc.home) {
162 if (loc.wide) {
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 }
buzbeeb03f4872012-06-11 15:22:11 -0700544 greenland::IntrinsicHelper::IntrinsicId id =
545 greenland::IntrinsicHelper::SetShadowFrameEntry;
546 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
547 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
548 llvm::Value* args[] = { newVal, tableSlot };
549 cUnit->irb->CreateCall(func, args);
550}
551
buzbee2cfc6392012-05-07 14:51:40 -0700552void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
553 RegLocation rlSrc1, int32_t imm)
554{
555 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
556 llvm::Value* src2 = cUnit->irb->getInt32(imm);
557 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
558 defineValue(cUnit, res, rlDest.origSReg);
559}
560
buzbee101305f2012-06-28 18:00:56 -0700561/*
562 * Process arguments for invoke. Note: this code is also used to
563 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
564 * The requirements are similar.
565 */
buzbee6969d502012-06-15 16:40:31 -0700566void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700567 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700568{
569 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
570 llvm::SmallVector<llvm::Value*, 10> args;
571 // Insert the invokeType
572 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
573 // Insert the method_idx
574 args.push_back(cUnit->irb->getInt32(info->index));
575 // Insert the optimization flags
576 args.push_back(cUnit->irb->getInt32(info->optFlags));
577 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700578 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700579 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
580 args.push_back(val);
581 i += info->args[i].wide ? 2 : 1;
582 }
583 /*
584 * Choose the invoke return type based on actual usage. Note: may
585 * be different than shorty. For example, if a function return value
586 * is not used, we'll treat this as a void invoke.
587 */
588 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700589 if (isFilledNewArray) {
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700590 id = greenland::IntrinsicHelper::HLFilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700591 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700592 id = greenland::IntrinsicHelper::HLInvokeVoid;
593 } else {
594 if (info->result.wide) {
595 if (info->result.fp) {
596 id = greenland::IntrinsicHelper::HLInvokeDouble;
597 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700598 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700599 }
600 } else if (info->result.ref) {
601 id = greenland::IntrinsicHelper::HLInvokeObj;
602 } else if (info->result.fp) {
603 id = greenland::IntrinsicHelper::HLInvokeFloat;
604 } else {
605 id = greenland::IntrinsicHelper::HLInvokeInt;
606 }
607 }
608 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
609 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
610 if (info->result.location != kLocInvalid) {
611 defineValue(cUnit, res, info->result.origSReg);
TDYa127890ea892012-08-22 10:49:42 -0700612 if (info->result.ref) {
613 setShadowFrameEntry(cUnit, (llvm::Value*)
614 cUnit->llvmValues.elemList[info->result.origSReg]);
615 }
buzbee6969d502012-06-15 16:40:31 -0700616 }
617}
618
buzbee101305f2012-06-28 18:00:56 -0700619void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
620 greenland::IntrinsicHelper::IntrinsicId id,
621 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700622{
buzbee6969d502012-06-15 16:40:31 -0700623 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700624 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700625 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
626 defineValue(cUnit, res, rlDest.origSReg);
627}
628
buzbee101305f2012-06-28 18:00:56 -0700629void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
630 RegLocation rlSrc)
631{
632 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700633 id = greenland::IntrinsicHelper::HLCheckCast;
buzbee101305f2012-06-28 18:00:56 -0700634 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
635 llvm::SmallVector<llvm::Value*, 2> args;
636 args.push_back(cUnit->irb->getInt32(type_idx));
637 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
638 cUnit->irb->CreateCall(intr, args);
639}
640
buzbee8fa0fda2012-06-27 15:44:52 -0700641void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
642 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700643{
644 greenland::IntrinsicHelper::IntrinsicId id;
645 id = greenland::IntrinsicHelper::NewInstance;
646 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
647 llvm::Value* index = cUnit->irb->getInt32(type_idx);
648 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
649 defineValue(cUnit, res, rlDest.origSReg);
650}
651
buzbee8fa0fda2012-06-27 15:44:52 -0700652void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
653 RegLocation rlDest, RegLocation rlSrc)
654{
655 greenland::IntrinsicHelper::IntrinsicId id;
656 id = greenland::IntrinsicHelper::NewArray;
657 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
658 llvm::SmallVector<llvm::Value*, 2> args;
659 args.push_back(cUnit->irb->getInt32(type_idx));
660 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
661 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
662 defineValue(cUnit, res, rlDest.origSReg);
663}
664
665void convertAget(CompilationUnit* cUnit, int optFlags,
666 greenland::IntrinsicHelper::IntrinsicId id,
667 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
668{
669 llvm::SmallVector<llvm::Value*, 3> args;
670 args.push_back(cUnit->irb->getInt32(optFlags));
671 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
672 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
673 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
674 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
675 defineValue(cUnit, res, rlDest.origSReg);
676}
677
678void convertAput(CompilationUnit* cUnit, int optFlags,
679 greenland::IntrinsicHelper::IntrinsicId id,
680 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
681{
682 llvm::SmallVector<llvm::Value*, 4> args;
683 args.push_back(cUnit->irb->getInt32(optFlags));
684 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
685 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
686 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
687 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
688 cUnit->irb->CreateCall(intr, args);
689}
690
buzbee101305f2012-06-28 18:00:56 -0700691void convertIget(CompilationUnit* cUnit, int optFlags,
692 greenland::IntrinsicHelper::IntrinsicId id,
693 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
694{
695 llvm::SmallVector<llvm::Value*, 3> args;
696 args.push_back(cUnit->irb->getInt32(optFlags));
697 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
698 args.push_back(cUnit->irb->getInt32(fieldIndex));
699 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
700 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
701 defineValue(cUnit, res, rlDest.origSReg);
702}
703
704void convertIput(CompilationUnit* cUnit, int optFlags,
705 greenland::IntrinsicHelper::IntrinsicId id,
706 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
707{
708 llvm::SmallVector<llvm::Value*, 4> args;
709 args.push_back(cUnit->irb->getInt32(optFlags));
710 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
711 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
712 args.push_back(cUnit->irb->getInt32(fieldIndex));
713 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
714 cUnit->irb->CreateCall(intr, args);
715}
716
buzbee8fa0fda2012-06-27 15:44:52 -0700717void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
718 RegLocation rlDest, RegLocation rlSrc)
719{
720 greenland::IntrinsicHelper::IntrinsicId id;
721 id = greenland::IntrinsicHelper::InstanceOf;
722 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
723 llvm::SmallVector<llvm::Value*, 2> args;
724 args.push_back(cUnit->irb->getInt32(type_idx));
725 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
726 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
727 defineValue(cUnit, res, rlDest.origSReg);
728}
729
buzbee101305f2012-06-28 18:00:56 -0700730void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
731 RegLocation rlSrc)
732{
733 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
734 cUnit->irb->getInt64Ty());
735 defineValue(cUnit, res, rlDest.origSReg);
736}
737
buzbee76592632012-06-29 15:18:35 -0700738void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
739 RegLocation rlSrc)
740{
741 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
742 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
743 defineValue(cUnit, res, rlDest.origSReg);
744}
745
746void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
747 RegLocation rlSrc)
748{
749 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
750 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
751 defineValue(cUnit, res, rlDest.origSReg);
752}
753
754void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
755 RegLocation rlSrc)
756{
757 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
758 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
759 defineValue(cUnit, res, rlDest.origSReg);
760}
761
762void convertWideComparison(CompilationUnit* cUnit,
763 greenland::IntrinsicHelper::IntrinsicId id,
764 RegLocation rlDest, RegLocation rlSrc1,
765 RegLocation rlSrc2)
766{
767 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
768 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
769 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
770 llvm::SmallVector<llvm::Value*, 2> args;
771 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
772 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
773 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
774 defineValue(cUnit, res, rlDest.origSReg);
775}
776
buzbee101305f2012-06-28 18:00:56 -0700777void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
778 RegLocation rlSrc,
779 greenland::IntrinsicHelper::IntrinsicId id)
780{
781 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700782 llvm::Value* res =
783 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
784 defineValue(cUnit, res, rlDest.origSReg);
785}
786
787void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
788 RegLocation rlSrc)
789{
790 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
791 defineValue(cUnit, res, rlDest.origSReg);
792}
793
794void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
795 RegLocation rlSrc)
796{
797 llvm::Value* res =
798 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
799 defineValue(cUnit, res, rlDest.origSReg);
800}
801
TDYa1274ec8ccd2012-08-11 07:04:57 -0700802void convertFPToInt(CompilationUnit* cUnit,
803 greenland::IntrinsicHelper::IntrinsicId id,
804 RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700805 RegLocation rlSrc)
806{
TDYa1274ec8ccd2012-08-11 07:04:57 -0700807 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
808 llvm::Value* res = cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
buzbee76592632012-06-29 15:18:35 -0700809 defineValue(cUnit, res, rlDest.origSReg);
810}
811
812
813void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
814 RegLocation rlSrc)
815{
816 llvm::Value* res =
817 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
818 defineValue(cUnit, res, rlDest.origSReg);
819}
820
821void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
822 RegLocation rlSrc)
823{
824 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
825 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700826 defineValue(cUnit, res, rlDest.origSReg);
827}
828
buzbee2cfc6392012-05-07 14:51:40 -0700829/*
830 * Target-independent code generation. Use only high-level
831 * load/store utilities here, or target-dependent genXX() handlers
832 * when necessary.
833 */
834bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
835 llvm::BasicBlock* llvmBB, LIR* labelList)
836{
837 bool res = false; // Assume success
838 RegLocation rlSrc[3];
839 RegLocation rlDest = badLoc;
buzbee2cfc6392012-05-07 14:51:40 -0700840 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee6969d502012-06-15 16:40:31 -0700841 uint32_t vB = mir->dalvikInsn.vB;
842 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700843 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700844
buzbeeb03f4872012-06-11 15:22:11 -0700845 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700846
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700847 if (cUnit->printMe) {
848 if ((int)opcode < kMirOpFirst) {
849 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x"
850 << std::hex << (int)opcode;
851 } else {
852 LOG(INFO) << ".. opcode 0x" << std::hex << (int)opcode;
853 }
854 }
855
buzbee2cfc6392012-05-07 14:51:40 -0700856 /* Prep Src and Dest locations */
857 int nextSreg = 0;
858 int nextLoc = 0;
859 int attrs = oatDataFlowAttributes[opcode];
860 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
861 if (attrs & DF_UA) {
862 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700863 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700864 nextSreg+= 2;
865 } else {
866 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
867 nextSreg++;
868 }
869 }
870 if (attrs & DF_UB) {
871 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700872 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700873 nextSreg+= 2;
874 } else {
875 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
876 nextSreg++;
877 }
878 }
879 if (attrs & DF_UC) {
880 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700881 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700882 } else {
883 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
884 }
885 }
886 if (attrs & DF_DA) {
887 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700888 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700889 } else {
buzbee15bf9802012-06-12 17:49:27 -0700890 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700891 if (rlDest.ref) {
892 objectDefinition = true;
893 }
buzbee2cfc6392012-05-07 14:51:40 -0700894 }
895 }
896
897 switch (opcode) {
898 case Instruction::NOP:
899 break;
900
901 case Instruction::MOVE:
902 case Instruction::MOVE_OBJECT:
903 case Instruction::MOVE_16:
904 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700905 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700906 case Instruction::MOVE_FROM16:
907 case Instruction::MOVE_WIDE:
908 case Instruction::MOVE_WIDE_16:
909 case Instruction::MOVE_WIDE_FROM16: {
910 /*
911 * Moves/copies are meaningless in pure SSA register form,
912 * but we need to preserve them for the conversion back into
913 * MIR (at least until we stop using the Dalvik register maps).
914 * Insert a dummy intrinsic copy call, which will be recognized
915 * by the quick path and removed by the portable path.
916 */
917 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
918 llvm::Value* res = emitCopy(cUnit, src, rlDest);
919 defineValue(cUnit, res, rlDest.origSReg);
920 }
921 break;
922
923 case Instruction::CONST:
924 case Instruction::CONST_4:
925 case Instruction::CONST_16: {
TDYa127347166a2012-08-23 12:23:44 -0700926 if (vB == 0) {
927 objectDefinition = true;
928 }
buzbee6969d502012-06-15 16:40:31 -0700929 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700930 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
931 defineValue(cUnit, res, rlDest.origSReg);
932 }
933 break;
934
935 case Instruction::CONST_WIDE_16:
936 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700937 // Sign extend to 64 bits
938 int64_t imm = static_cast<int32_t>(vB);
939 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700940 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
941 defineValue(cUnit, res, rlDest.origSReg);
942 }
943 break;
944
945 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700946 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700947 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
948 defineValue(cUnit, res, rlDest.origSReg);
949 }
950 break;
951
952 case Instruction::CONST_WIDE: {
953 llvm::Constant* immValue =
954 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
955 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
956 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700957 }
958 break;
buzbee2cfc6392012-05-07 14:51:40 -0700959 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700960 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700961 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
962 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
963 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700964 }
965 break;
966
buzbee8fa0fda2012-06-27 15:44:52 -0700967 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700968 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700969 rlSrc[0]);
970 break;
971 case Instruction::SPUT:
972 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700973 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700974 rlSrc[0]);
975 } else {
buzbee76592632012-06-29 15:18:35 -0700976 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700977 }
978 break;
979 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700980 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700981 rlSrc[0]);
982 break;
983 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700984 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700985 break;
986 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700987 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700988 break;
989 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -0700990 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700991 break;
992 case Instruction::SPUT_WIDE:
993 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700994 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -0700995 rlSrc[0]);
996 } else {
buzbee76592632012-06-29 15:18:35 -0700997 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -0700998 rlSrc[0]);
999 }
1000 break;
1001
1002 case Instruction::SGET_OBJECT:
1003 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
1004 break;
1005 case Instruction::SGET:
1006 if (rlDest.fp) {
1007 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
1008 } else {
1009 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
1010 }
1011 break;
1012 case Instruction::SGET_BOOLEAN:
1013 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
1014 break;
1015 case Instruction::SGET_BYTE:
1016 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
1017 break;
1018 case Instruction::SGET_CHAR:
1019 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
1020 break;
1021 case Instruction::SGET_SHORT:
1022 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
1023 break;
1024 case Instruction::SGET_WIDE:
1025 if (rlDest.fp) {
1026 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
1027 rlDest);
1028 } else {
1029 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001030 }
1031 break;
buzbee2cfc6392012-05-07 14:51:40 -07001032
1033 case Instruction::RETURN_WIDE:
1034 case Instruction::RETURN:
1035 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -07001036 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001037 emitSuspendCheck(cUnit);
1038 }
buzbeeb03f4872012-06-11 15:22:11 -07001039 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001040 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
1041 bb->hasReturn = true;
1042 }
1043 break;
1044
1045 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001046 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001047 emitSuspendCheck(cUnit);
1048 }
buzbeeb03f4872012-06-11 15:22:11 -07001049 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001050 cUnit->irb->CreateRetVoid();
1051 bb->hasReturn = true;
1052 }
1053 break;
1054
1055 case Instruction::IF_EQ:
1056 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1057 break;
1058 case Instruction::IF_NE:
1059 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1060 break;
1061 case Instruction::IF_LT:
1062 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1063 break;
1064 case Instruction::IF_GE:
1065 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1066 break;
1067 case Instruction::IF_GT:
1068 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1069 break;
1070 case Instruction::IF_LE:
1071 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1072 break;
1073 case Instruction::IF_EQZ:
1074 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1075 break;
1076 case Instruction::IF_NEZ:
1077 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1078 break;
1079 case Instruction::IF_LTZ:
1080 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1081 break;
1082 case Instruction::IF_GEZ:
1083 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1084 break;
1085 case Instruction::IF_GTZ:
1086 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1087 break;
1088 case Instruction::IF_LEZ:
1089 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1090 break;
1091
1092 case Instruction::GOTO:
1093 case Instruction::GOTO_16:
1094 case Instruction::GOTO_32: {
1095 if (bb->taken->startOffset <= bb->startOffset) {
1096 emitSuspendCheck(cUnit);
1097 }
1098 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1099 }
1100 break;
1101
1102 case Instruction::ADD_LONG:
1103 case Instruction::ADD_LONG_2ADDR:
1104 case Instruction::ADD_INT:
1105 case Instruction::ADD_INT_2ADDR:
1106 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1107 break;
1108 case Instruction::SUB_LONG:
1109 case Instruction::SUB_LONG_2ADDR:
1110 case Instruction::SUB_INT:
1111 case Instruction::SUB_INT_2ADDR:
1112 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1113 break;
1114 case Instruction::MUL_LONG:
1115 case Instruction::MUL_LONG_2ADDR:
1116 case Instruction::MUL_INT:
1117 case Instruction::MUL_INT_2ADDR:
1118 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1119 break;
1120 case Instruction::DIV_LONG:
1121 case Instruction::DIV_LONG_2ADDR:
1122 case Instruction::DIV_INT:
1123 case Instruction::DIV_INT_2ADDR:
1124 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1125 break;
1126 case Instruction::REM_LONG:
1127 case Instruction::REM_LONG_2ADDR:
1128 case Instruction::REM_INT:
1129 case Instruction::REM_INT_2ADDR:
1130 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1131 break;
1132 case Instruction::AND_LONG:
1133 case Instruction::AND_LONG_2ADDR:
1134 case Instruction::AND_INT:
1135 case Instruction::AND_INT_2ADDR:
1136 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1137 break;
1138 case Instruction::OR_LONG:
1139 case Instruction::OR_LONG_2ADDR:
1140 case Instruction::OR_INT:
1141 case Instruction::OR_INT_2ADDR:
1142 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1143 break;
1144 case Instruction::XOR_LONG:
1145 case Instruction::XOR_LONG_2ADDR:
1146 case Instruction::XOR_INT:
1147 case Instruction::XOR_INT_2ADDR:
1148 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1149 break;
1150 case Instruction::SHL_LONG:
1151 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001152 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1153 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001154 break;
buzbee2cfc6392012-05-07 14:51:40 -07001155 case Instruction::SHL_INT:
1156 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001157 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1158 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001159 break;
1160 case Instruction::SHR_LONG:
1161 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001162 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1163 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001164 break;
buzbee2cfc6392012-05-07 14:51:40 -07001165 case Instruction::SHR_INT:
1166 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001167 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1168 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001169 break;
1170 case Instruction::USHR_LONG:
1171 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001172 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1173 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001174 break;
buzbee2cfc6392012-05-07 14:51:40 -07001175 case Instruction::USHR_INT:
1176 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001177 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1178 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001179 break;
1180
1181 case Instruction::ADD_INT_LIT16:
1182 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001183 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001184 break;
1185 case Instruction::RSUB_INT:
1186 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001187 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001188 break;
1189 case Instruction::MUL_INT_LIT16:
1190 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001191 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001192 break;
1193 case Instruction::DIV_INT_LIT16:
1194 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001195 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001196 break;
1197 case Instruction::REM_INT_LIT16:
1198 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001199 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001200 break;
1201 case Instruction::AND_INT_LIT16:
1202 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001203 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001204 break;
1205 case Instruction::OR_INT_LIT16:
1206 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001207 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001208 break;
1209 case Instruction::XOR_INT_LIT16:
1210 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001211 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001212 break;
1213 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001214 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1215 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001216 break;
1217 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001218 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1219 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001220 break;
1221 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001222 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1223 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001224 break;
1225
1226 case Instruction::ADD_FLOAT:
1227 case Instruction::ADD_FLOAT_2ADDR:
1228 case Instruction::ADD_DOUBLE:
1229 case Instruction::ADD_DOUBLE_2ADDR:
1230 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1231 break;
1232
1233 case Instruction::SUB_FLOAT:
1234 case Instruction::SUB_FLOAT_2ADDR:
1235 case Instruction::SUB_DOUBLE:
1236 case Instruction::SUB_DOUBLE_2ADDR:
1237 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1238 break;
1239
1240 case Instruction::MUL_FLOAT:
1241 case Instruction::MUL_FLOAT_2ADDR:
1242 case Instruction::MUL_DOUBLE:
1243 case Instruction::MUL_DOUBLE_2ADDR:
1244 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1245 break;
1246
1247 case Instruction::DIV_FLOAT:
1248 case Instruction::DIV_FLOAT_2ADDR:
1249 case Instruction::DIV_DOUBLE:
1250 case Instruction::DIV_DOUBLE_2ADDR:
1251 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1252 break;
1253
1254 case Instruction::REM_FLOAT:
1255 case Instruction::REM_FLOAT_2ADDR:
1256 case Instruction::REM_DOUBLE:
1257 case Instruction::REM_DOUBLE_2ADDR:
1258 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1259 break;
1260
buzbee6969d502012-06-15 16:40:31 -07001261 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001262 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1263 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001264 break;
1265 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001266 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1267 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001268 break;
1269
1270 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001271 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1272 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001273 break;
1274 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001275 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1276 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001277 break;
1278
1279 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001280 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1281 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001282 break;
1283 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001284 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1285 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001286 break;
1287
1288 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001289 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1290 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001291 break;
1292 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001293 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1294 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001295 break;
1296
1297 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001298 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1299 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001300 break;
1301 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001302 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1303 false /* NewFilledArray */);
1304 break;
1305 case Instruction::FILLED_NEW_ARRAY:
1306 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1307 true /* NewFilledArray */);
1308 break;
1309 case Instruction::FILLED_NEW_ARRAY_RANGE:
1310 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1311 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001312 break;
1313
1314 case Instruction::CONST_STRING:
1315 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001316 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1317 rlDest);
1318 break;
1319
1320 case Instruction::CONST_CLASS:
1321 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1322 rlDest);
1323 break;
1324
1325 case Instruction::CHECK_CAST:
1326 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001327 break;
1328
buzbee4f1181f2012-06-22 13:52:12 -07001329 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001330 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001331 break;
1332
buzbee32412962012-06-26 16:27:56 -07001333 case Instruction::MOVE_EXCEPTION:
1334 convertMoveException(cUnit, rlDest);
1335 break;
1336
1337 case Instruction::THROW:
1338 convertThrow(cUnit, rlSrc[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001339 /*
1340 * If this throw is standalone, terminate.
1341 * If it might rethrow, force termination
1342 * of the following block.
1343 */
1344 if (bb->fallThrough == NULL) {
1345 cUnit->irb->CreateUnreachable();
1346 } else {
1347 bb->fallThrough->fallThrough = NULL;
1348 bb->fallThrough->taken = NULL;
1349 }
buzbee32412962012-06-26 16:27:56 -07001350 break;
1351
buzbee2cfc6392012-05-07 14:51:40 -07001352 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001353 case Instruction::MOVE_RESULT:
1354 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001355 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001356 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001357 */
jeffhao9a4f0032012-08-30 16:17:40 -07001358 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001359 break;
1360
1361 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001362 convertMonitorEnterExit(cUnit, optFlags,
1363 greenland::IntrinsicHelper::MonitorEnter,
1364 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001365 break;
1366
1367 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001368 convertMonitorEnterExit(cUnit, optFlags,
1369 greenland::IntrinsicHelper::MonitorExit,
1370 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001371 break;
1372
1373 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001374 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001375 break;
1376
1377 case Instruction::NEW_ARRAY:
1378 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1379 break;
1380
1381 case Instruction::INSTANCE_OF:
1382 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1383 break;
1384
1385 case Instruction::AGET:
1386 if (rlDest.fp) {
1387 convertAget(cUnit, optFlags,
1388 greenland::IntrinsicHelper::HLArrayGetFloat,
1389 rlDest, rlSrc[0], rlSrc[1]);
1390 } else {
1391 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1392 rlDest, rlSrc[0], rlSrc[1]);
1393 }
1394 break;
1395 case Instruction::AGET_OBJECT:
1396 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1397 rlDest, rlSrc[0], rlSrc[1]);
1398 break;
1399 case Instruction::AGET_BOOLEAN:
1400 convertAget(cUnit, optFlags,
1401 greenland::IntrinsicHelper::HLArrayGetBoolean,
1402 rlDest, rlSrc[0], rlSrc[1]);
1403 break;
1404 case Instruction::AGET_BYTE:
1405 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1406 rlDest, rlSrc[0], rlSrc[1]);
1407 break;
1408 case Instruction::AGET_CHAR:
1409 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1410 rlDest, rlSrc[0], rlSrc[1]);
1411 break;
1412 case Instruction::AGET_SHORT:
1413 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1414 rlDest, rlSrc[0], rlSrc[1]);
1415 break;
1416 case Instruction::AGET_WIDE:
1417 if (rlDest.fp) {
1418 convertAget(cUnit, optFlags,
1419 greenland::IntrinsicHelper::HLArrayGetDouble,
1420 rlDest, rlSrc[0], rlSrc[1]);
1421 } else {
1422 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1423 rlDest, rlSrc[0], rlSrc[1]);
1424 }
1425 break;
1426
1427 case Instruction::APUT:
1428 if (rlSrc[0].fp) {
1429 convertAput(cUnit, optFlags,
1430 greenland::IntrinsicHelper::HLArrayPutFloat,
1431 rlSrc[0], rlSrc[1], rlSrc[2]);
1432 } else {
1433 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1434 rlSrc[0], rlSrc[1], rlSrc[2]);
1435 }
1436 break;
1437 case Instruction::APUT_OBJECT:
1438 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1439 rlSrc[0], rlSrc[1], rlSrc[2]);
1440 break;
1441 case Instruction::APUT_BOOLEAN:
1442 convertAput(cUnit, optFlags,
1443 greenland::IntrinsicHelper::HLArrayPutBoolean,
1444 rlSrc[0], rlSrc[1], rlSrc[2]);
1445 break;
1446 case Instruction::APUT_BYTE:
1447 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1448 rlSrc[0], rlSrc[1], rlSrc[2]);
1449 break;
1450 case Instruction::APUT_CHAR:
1451 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1452 rlSrc[0], rlSrc[1], rlSrc[2]);
1453 break;
1454 case Instruction::APUT_SHORT:
1455 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1456 rlSrc[0], rlSrc[1], rlSrc[2]);
1457 break;
1458 case Instruction::APUT_WIDE:
1459 if (rlSrc[0].fp) {
1460 convertAput(cUnit, optFlags,
1461 greenland::IntrinsicHelper::HLArrayPutDouble,
1462 rlSrc[0], rlSrc[1], rlSrc[2]);
1463 } else {
1464 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1465 rlSrc[0], rlSrc[1], rlSrc[2]);
1466 }
1467 break;
1468
buzbee101305f2012-06-28 18:00:56 -07001469 case Instruction::IGET:
1470 if (rlDest.fp) {
1471 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001472 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001473 } else {
1474 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001475 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001476 }
buzbee2cfc6392012-05-07 14:51:40 -07001477 break;
buzbee101305f2012-06-28 18:00:56 -07001478 case Instruction::IGET_OBJECT:
1479 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001480 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001481 break;
1482 case Instruction::IGET_BOOLEAN:
1483 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001484 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001485 break;
1486 case Instruction::IGET_BYTE:
1487 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001488 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001489 break;
1490 case Instruction::IGET_CHAR:
1491 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001492 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001493 break;
1494 case Instruction::IGET_SHORT:
1495 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001496 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001497 break;
1498 case Instruction::IGET_WIDE:
1499 if (rlDest.fp) {
1500 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001501 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001502 } else {
1503 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001504 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001505 }
1506 break;
1507 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001508 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001509 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1510 rlSrc[0], rlSrc[1], vC);
1511 } else {
1512 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1513 rlSrc[0], rlSrc[1], vC);
1514 }
1515 break;
1516 case Instruction::IPUT_OBJECT:
1517 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1518 rlSrc[0], rlSrc[1], vC);
1519 break;
1520 case Instruction::IPUT_BOOLEAN:
1521 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1522 rlSrc[0], rlSrc[1], vC);
1523 break;
1524 case Instruction::IPUT_BYTE:
1525 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1526 rlSrc[0], rlSrc[1], vC);
1527 break;
1528 case Instruction::IPUT_CHAR:
1529 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1530 rlSrc[0], rlSrc[1], vC);
1531 break;
1532 case Instruction::IPUT_SHORT:
1533 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1534 rlSrc[0], rlSrc[1], vC);
1535 break;
1536 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001537 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001538 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1539 rlSrc[0], rlSrc[1], vC);
1540 } else {
1541 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1542 rlSrc[0], rlSrc[1], vC);
1543 }
buzbee2cfc6392012-05-07 14:51:40 -07001544 break;
1545
1546 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001547 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001548 break;
1549
buzbee76592632012-06-29 15:18:35 -07001550 case Instruction::LONG_TO_INT:
1551 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1552 break;
1553
buzbee101305f2012-06-28 18:00:56 -07001554 case Instruction::INT_TO_LONG:
1555 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001556 break;
1557
buzbee101305f2012-06-28 18:00:56 -07001558 case Instruction::INT_TO_CHAR:
1559 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1560 greenland::IntrinsicHelper::IntToChar);
1561 break;
1562 case Instruction::INT_TO_BYTE:
1563 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1564 greenland::IntrinsicHelper::IntToByte);
1565 break;
1566 case Instruction::INT_TO_SHORT:
1567 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1568 greenland::IntrinsicHelper::IntToShort);
1569 break;
1570
buzbee76592632012-06-29 15:18:35 -07001571 case Instruction::INT_TO_FLOAT:
1572 case Instruction::LONG_TO_FLOAT:
1573 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001574 break;
1575
buzbee76592632012-06-29 15:18:35 -07001576 case Instruction::INT_TO_DOUBLE:
1577 case Instruction::LONG_TO_DOUBLE:
1578 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001579 break;
1580
buzbee76592632012-06-29 15:18:35 -07001581 case Instruction::FLOAT_TO_DOUBLE:
1582 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001583 break;
1584
buzbee76592632012-06-29 15:18:35 -07001585 case Instruction::DOUBLE_TO_FLOAT:
1586 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001587 break;
1588
1589 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001590 case Instruction::NEG_INT:
1591 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001592 break;
1593
1594 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001595 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001596 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001597 break;
1598
buzbee76592632012-06-29 15:18:35 -07001599 case Instruction::NOT_LONG:
1600 case Instruction::NOT_INT:
1601 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001602 break;
1603
buzbee2cfc6392012-05-07 14:51:40 -07001604 case Instruction::FLOAT_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001605 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2I, rlDest, rlSrc[0]);
1606 break;
1607
buzbee2cfc6392012-05-07 14:51:40 -07001608 case Instruction::DOUBLE_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001609 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2I, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001610 break;
1611
buzbee76592632012-06-29 15:18:35 -07001612 case Instruction::FLOAT_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001613 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2L, rlDest, rlSrc[0]);
1614 break;
1615
buzbee76592632012-06-29 15:18:35 -07001616 case Instruction::DOUBLE_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001617 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2L, rlDest, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001618 break;
1619
1620 case Instruction::CMPL_FLOAT:
1621 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1622 rlDest, rlSrc[0], rlSrc[1]);
1623 break;
1624 case Instruction::CMPG_FLOAT:
1625 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1626 rlDest, rlSrc[0], rlSrc[1]);
1627 break;
1628 case Instruction::CMPL_DOUBLE:
1629 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1630 rlDest, rlSrc[0], rlSrc[1]);
1631 break;
1632 case Instruction::CMPG_DOUBLE:
1633 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1634 rlDest, rlSrc[0], rlSrc[1]);
1635 break;
1636 case Instruction::CMP_LONG:
1637 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1638 rlDest, rlSrc[0], rlSrc[1]);
1639 break;
1640
buzbee76592632012-06-29 15:18:35 -07001641 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001642 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001643 break;
1644
1645 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001646 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001647 break;
buzbee2cfc6392012-05-07 14:51:40 -07001648
1649 default:
buzbee32412962012-06-26 16:27:56 -07001650 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001651 res = true;
1652 }
buzbeeb03f4872012-06-11 15:22:11 -07001653 if (objectDefinition) {
1654 setShadowFrameEntry(cUnit, (llvm::Value*)
1655 cUnit->llvmValues.elemList[rlDest.origSReg]);
1656 }
buzbee2cfc6392012-05-07 14:51:40 -07001657 return res;
1658}
1659
1660/* Extended MIR instructions like PHI */
1661void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1662 llvm::BasicBlock* llvmBB)
1663{
1664
1665 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1666 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001667 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001668 /*
1669 * The Art compiler's Phi nodes only handle 32-bit operands,
1670 * representing wide values using a matched set of Phi nodes
1671 * for the lower and upper halves. In the llvm world, we only
1672 * want a single Phi for wides. Here we will simply discard
1673 * the Phi node representing the high word.
1674 */
1675 if (rlDest.highWord) {
1676 return; // No Phi node - handled via low word
1677 }
1678 int* incoming = (int*)mir->dalvikInsn.vB;
buzbee2cfc6392012-05-07 14:51:40 -07001679 llvm::Type* phiType =
1680 llvmTypeFromLocRec(cUnit, rlDest);
1681 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1682 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1683 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001684 // Don't check width here.
1685 loc = oatGetRawSrc(cUnit, mir, i);
1686 DCHECK_EQ(rlDest.wide, loc.wide);
1687 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1688 DCHECK_EQ(rlDest.fp, loc.fp);
1689 DCHECK_EQ(rlDest.core, loc.core);
1690 DCHECK_EQ(rlDest.ref, loc.ref);
buzbeed1643e42012-09-05 14:06:51 -07001691 SafeMap<unsigned int, unsigned int>::iterator it;
1692 it = cUnit->blockIdMap.find(incoming[i]);
1693 DCHECK(it != cUnit->blockIdMap.end());
buzbee2cfc6392012-05-07 14:51:40 -07001694 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
buzbeed1643e42012-09-05 14:06:51 -07001695 getLLVMBlock(cUnit, it->second));
buzbee2cfc6392012-05-07 14:51:40 -07001696 }
1697 defineValue(cUnit, phi, rlDest.origSReg);
1698 break;
1699 }
1700 case kMirOpCopy: {
1701 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1702 break;
1703 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001704 case kMirOpNop:
1705 if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
1706 (bb->fallThrough == NULL)) {
1707 cUnit->irb->CreateUnreachable();
1708 }
1709 break;
1710
buzbee2cfc6392012-05-07 14:51:40 -07001711#if defined(TARGET_ARM)
1712 case kMirOpFusedCmplFloat:
1713 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1714 break;
1715 case kMirOpFusedCmpgFloat:
1716 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1717 break;
1718 case kMirOpFusedCmplDouble:
1719 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1720 break;
1721 case kMirOpFusedCmpgDouble:
1722 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1723 break;
1724 case kMirOpFusedCmpLong:
1725 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1726 break;
1727#endif
1728 default:
1729 break;
1730 }
1731}
1732
1733void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1734{
1735 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001736 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001737 arrayRef.push_back(cUnit->irb->getInt32(offset));
1738 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1739 cUnit->irb->SetDexOffset(node);
1740}
1741
1742// Attach method info as metadata to special intrinsic
1743void setMethodInfo(CompilationUnit* cUnit)
1744{
1745 // We don't want dex offset on this
1746 cUnit->irb->SetDexOffset(NULL);
1747 greenland::IntrinsicHelper::IntrinsicId id;
1748 id = greenland::IntrinsicHelper::MethodInfo;
1749 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1750 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1751 llvm::SmallVector<llvm::Value*, 2> regInfo;
1752 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1753 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1754 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1755 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1756 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1757 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1758 inst->setMetadata("RegInfo", regInfoNode);
1759 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1760 llvm::SmallVector<llvm::Value*, 50> pmap;
1761 for (int i = 0; i < promoSize; i++) {
1762 PromotionMap* p = &cUnit->promotionMap[i];
1763 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1764 ((p->fpReg & 0xff) << 16) |
1765 ((p->coreReg & 0xff) << 8) |
1766 ((p->fpLocation & 0xf) << 4) |
1767 (p->coreLocation & 0xf);
1768 pmap.push_back(cUnit->irb->getInt32(mapData));
1769 }
1770 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1771 inst->setMetadata("PromotionMap", mapNode);
1772 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1773}
1774
1775/* Handle the content in each basic block */
1776bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1777{
buzbeed1643e42012-09-05 14:06:51 -07001778 if (bb->blockType == kDead) return false;
buzbee2cfc6392012-05-07 14:51:40 -07001779 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
Shih-wei Liaob2596522012-09-14 16:36:11 -07001780 cUnit->irb->SetInsertPoint(llvmBB);
1781 setDexOffset(cUnit, bb->startOffset);
buzbee2cfc6392012-05-07 14:51:40 -07001782
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001783 if (cUnit->printMe) {
1784 LOG(INFO) << "................................";
1785 LOG(INFO) << "Block id " << bb->id;
1786 if (llvmBB != NULL) {
1787 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1788 } else {
1789 LOG(INFO) << "llvmBB is NULL";
1790 }
1791 }
1792
buzbee2cfc6392012-05-07 14:51:40 -07001793 if (bb->blockType == kEntryBlock) {
1794 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001795 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1796 cUnit->numDalvikRegisters, true,
1797 kAllocMisc);
1798 for (int i = 0; i < cUnit->numSSARegs; i++) {
1799 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1800 }
1801 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1802 if (canBeRef[i]) {
1803 cUnit->numShadowFrameEntries++;
1804 }
1805 }
1806 if (cUnit->numShadowFrameEntries > 0) {
1807 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1808 cUnit->numShadowFrameEntries, true,
1809 kAllocMisc);
1810 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1811 if (canBeRef[i]) {
1812 cUnit->shadowMap[j++] = i;
1813 }
1814 }
buzbeeb03f4872012-06-11 15:22:11 -07001815 }
Shih-wei Liao569daf12012-08-10 23:22:33 -07001816 greenland::IntrinsicHelper::IntrinsicId id =
1817 greenland::IntrinsicHelper::AllocaShadowFrame;
1818 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1819 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1820 cUnit->irb->CreateCall(func, entries);
buzbee2cfc6392012-05-07 14:51:40 -07001821 } else if (bb->blockType == kExitBlock) {
1822 /*
1823 * Because of the differences between how MIR/LIR and llvm handle exit
1824 * blocks, we won't explicitly covert them. On the llvm-to-lir
1825 * path, it will need to be regenereated.
1826 */
1827 return false;
buzbee6969d502012-06-15 16:40:31 -07001828 } else if (bb->blockType == kExceptionHandling) {
1829 /*
1830 * Because we're deferring null checking, delete the associated empty
1831 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001832 */
1833 llvmBB->eraseFromParent();
1834 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001835 }
1836
1837 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1838
1839 setDexOffset(cUnit, mir->offset);
1840
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001841 int opcode = mir->dalvikInsn.opcode;
1842 Instruction::Format dalvikFormat =
1843 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001844
1845 /* If we're compiling for the debugger, generate an update callout */
1846 if (cUnit->genDebugger) {
1847 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1848 //genDebuggerUpdate(cUnit, mir->offset);
1849 }
1850
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001851 if (opcode == kMirOpCheck) {
1852 // Combine check and work halves of throwing instruction.
1853 MIR* workHalf = mir->meta.throwInsn;
1854 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
1855 opcode = mir->dalvikInsn.opcode;
1856 SSARepresentation* ssaRep = workHalf->ssaRep;
1857 workHalf->ssaRep = mir->ssaRep;
1858 mir->ssaRep = ssaRep;
1859 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1860 if (bb->successorBlockList.blockListType == kCatch) {
1861 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
1862 greenland::IntrinsicHelper::CatchTargets);
1863 llvm::Value* switchKey =
1864 cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
1865 GrowableListIterator iter;
1866 oatGrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
1867 // New basic block to use for work half
1868 llvm::BasicBlock* workBB =
1869 llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
1870 llvm::SwitchInst* sw =
1871 cUnit->irb->CreateSwitch(switchKey, workBB,
1872 bb->successorBlockList.blocks.numUsed);
1873 while (true) {
1874 SuccessorBlockInfo *successorBlockInfo =
1875 (SuccessorBlockInfo *) oatGrowableListIteratorNext(&iter);
1876 if (successorBlockInfo == NULL) break;
1877 llvm::BasicBlock *target =
1878 getLLVMBlock(cUnit, successorBlockInfo->block->id);
1879 int typeIndex = successorBlockInfo->key;
1880 sw->addCase(cUnit->irb->getInt32(typeIndex), target);
1881 }
1882 llvmBB = workBB;
1883 cUnit->irb->SetInsertPoint(llvmBB);
1884 }
1885 }
1886
1887 if (opcode >= kMirOpFirst) {
buzbee2cfc6392012-05-07 14:51:40 -07001888 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1889 continue;
1890 }
1891
1892 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1893 NULL /* labelList */);
1894 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001895 Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001896 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001897 mir->offset, opcode,
buzbee2cfc6392012-05-07 14:51:40 -07001898 Instruction::Name(dalvikOpcode),
1899 dalvikFormat);
1900 }
1901 }
1902
buzbee4be777b2012-07-12 14:38:18 -07001903 if (bb->blockType == kEntryBlock) {
1904 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1905 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001906 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1907 }
1908
1909 return false;
1910}
1911
buzbee4f4dfc72012-07-02 14:54:44 -07001912char remapShorty(char shortyType) {
1913 /*
1914 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1915 * and longs/doubles are represented as a pair of registers. When sub-word
1916 * arguments (and method results) are passed, they are extended to Dalvik
1917 * virtual register containers. Because llvm is picky about type consistency,
1918 * we must either cast the "real" type to 32-bit container multiple Dalvik
1919 * register types, or always use the expanded values.
1920 * Here, we're doing the latter. We map the shorty signature to container
1921 * types (which is valid so long as we always do a real expansion of passed
1922 * arguments and field loads).
1923 */
1924 switch(shortyType) {
1925 case 'Z' : shortyType = 'I'; break;
1926 case 'B' : shortyType = 'I'; break;
1927 case 'S' : shortyType = 'I'; break;
1928 case 'C' : shortyType = 'I'; break;
1929 default: break;
1930 }
1931 return shortyType;
1932}
1933
buzbee2cfc6392012-05-07 14:51:40 -07001934llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1935
1936 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001937 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001938 greenland::kAccurate);
1939
1940 // Get argument type
1941 std::vector<llvm::Type*> args_type;
1942
1943 // method object
1944 args_type.push_back(cUnit->irb->GetJMethodTy());
1945
1946 // Do we have a "this"?
1947 if ((cUnit->access_flags & kAccStatic) == 0) {
1948 args_type.push_back(cUnit->irb->GetJObjectTy());
1949 }
1950
1951 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001952 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001953 greenland::kAccurate));
1954 }
1955
1956 return llvm::FunctionType::get(ret_type, args_type, false);
1957}
1958
1959bool createFunction(CompilationUnit* cUnit) {
1960 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1961 /* with_signature */ false));
1962 llvm::FunctionType* func_type = getFunctionType(cUnit);
1963
1964 if (func_type == NULL) {
1965 return false;
1966 }
1967
1968 cUnit->func = llvm::Function::Create(func_type,
1969 llvm::Function::ExternalLinkage,
1970 func_name, cUnit->module);
1971
1972 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1973 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1974
1975 arg_iter->setName("method");
1976 ++arg_iter;
1977
1978 int startSReg = cUnit->numRegs;
1979
1980 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1981 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1982 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1983 }
1984
1985 return true;
1986}
1987
1988bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1989{
1990 // Skip the exit block
buzbeed1643e42012-09-05 14:06:51 -07001991 if ((bb->blockType == kDead) ||(bb->blockType == kExitBlock)) {
buzbee2cfc6392012-05-07 14:51:40 -07001992 cUnit->idToBlockMap.Put(bb->id, NULL);
1993 } else {
1994 int offset = bb->startOffset;
1995 bool entryBlock = (bb->blockType == kEntryBlock);
1996 llvm::BasicBlock* llvmBB =
1997 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
buzbee8320f382012-09-11 16:29:42 -07001998 StringPrintf(kLabelFormat, bb->catchEntry ? kCatchBlock :
1999 kNormalBlock, offset, bb->id), cUnit->func);
buzbee2cfc6392012-05-07 14:51:40 -07002000 if (entryBlock) {
2001 cUnit->entryBB = llvmBB;
2002 cUnit->placeholderBB =
2003 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
2004 cUnit->func);
2005 }
2006 cUnit->idToBlockMap.Put(bb->id, llvmBB);
2007 }
2008 return false;
2009}
2010
2011
2012/*
2013 * Convert MIR to LLVM_IR
2014 * o For each ssa name, create LLVM named value. Type these
2015 * appropriately, and ignore high half of wide and double operands.
2016 * o For each MIR basic block, create an LLVM basic block.
2017 * o Iterate through the MIR a basic block at a time, setting arguments
2018 * to recovered ssa name.
2019 */
2020void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
2021{
2022 initIR(cUnit);
2023 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
2024
2025 // Create the function
2026 createFunction(cUnit);
2027
2028 // Create an LLVM basic block for each MIR block in dfs preorder
2029 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
2030 kPreOrderDFSTraversal, false /* isIterative */);
2031 /*
2032 * Create an llvm named value for each MIR SSA name. Note: we'll use
2033 * placeholders for all non-argument values (because we haven't seen
2034 * the definition yet).
2035 */
2036 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2037 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2038 arg_iter++; /* Skip path method */
2039 for (int i = 0; i < cUnit->numSSARegs; i++) {
2040 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07002041 RegLocation rlTemp = cUnit->regLocation[i];
2042 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07002043 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
2044 } else if ((i < cUnit->numRegs) ||
2045 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07002046 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
2047 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07002048 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
2049 val->setName(llvmSSAName(cUnit, i));
buzbee2cfc6392012-05-07 14:51:40 -07002050 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
buzbee2cfc6392012-05-07 14:51:40 -07002051 } else {
2052 // Recover previously-created argument values
2053 llvm::Value* argVal = arg_iter++;
2054 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
2055 }
2056 }
buzbee2cfc6392012-05-07 14:51:40 -07002057
2058 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
2059 kPreOrderDFSTraversal, false /* Iterative */);
2060
buzbee4be777b2012-07-12 14:38:18 -07002061 /*
2062 * In a few rare cases of verification failure, the verifier will
2063 * replace one or more Dalvik opcodes with the special
2064 * throw-verification-failure opcode. This can leave the SSA graph
2065 * in an invalid state, as definitions may be lost, while uses retained.
2066 * To work around this problem, we insert placeholder definitions for
2067 * all Dalvik SSA regs in the "placeholder" block. Here, after
2068 * bitcode conversion is complete, we examine those placeholder definitions
2069 * and delete any with no references (which normally is all of them).
2070 *
2071 * If any definitions remain, we link the placeholder block into the
2072 * CFG. Otherwise, it is deleted.
2073 */
2074 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
2075 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
2076 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2077 DCHECK(inst != NULL);
2078 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2079 DCHECK(val != NULL);
2080 if (val->getNumUses() == 0) {
2081 inst->eraseFromParent();
2082 }
2083 }
2084 setDexOffset(cUnit, 0);
2085 if (cUnit->placeholderBB->empty()) {
2086 cUnit->placeholderBB->eraseFromParent();
2087 } else {
2088 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2089 cUnit->irb->CreateBr(cUnit->entryTargetBB);
2090 cUnit->entryTargetBB = cUnit->placeholderBB;
2091 }
2092 cUnit->irb->SetInsertPoint(cUnit->entryBB);
2093 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07002094
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002095 if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
2096 if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
2097 LOG(INFO) << "Bitcode verification FAILED for "
2098 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
2099 << " of size " << cUnit->insnsSize;
2100 cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
2101 }
2102 }
buzbee2cfc6392012-05-07 14:51:40 -07002103
buzbeead8f15e2012-06-18 14:49:45 -07002104 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
2105 // Write bitcode to file
2106 std::string errmsg;
2107 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
2108 oatReplaceSpecialChars(fname);
2109 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07002110 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002111
buzbeead8f15e2012-06-18 14:49:45 -07002112 llvm::OwningPtr<llvm::tool_output_file> out_file(
2113 new llvm::tool_output_file(fname.c_str(), errmsg,
2114 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002115
buzbeead8f15e2012-06-18 14:49:45 -07002116 if (!errmsg.empty()) {
2117 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2118 }
2119
2120 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2121 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002122 }
buzbee2cfc6392012-05-07 14:51:40 -07002123}
2124
2125RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2126 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002127 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002128 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2129 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002130 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002131 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002132 // FIXME: need to be more robust, handle FP and be in a position to
2133 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002134 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2135 memset(&res, 0, sizeof(res));
2136 res.location = kLocPhysReg;
2137 res.lowReg = oatAllocTemp(cUnit);
2138 res.home = true;
2139 res.sRegLow = INVALID_SREG;
2140 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002141 llvm::Type* ty = val->getType();
2142 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2143 (ty == cUnit->irb->getDoubleTy()));
2144 if (res.wide) {
2145 res.highReg = oatAllocTemp(cUnit);
2146 }
buzbee4f1181f2012-06-22 13:52:12 -07002147 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002148 } else {
2149 DCHECK_EQ(valName[0], 'v');
2150 int baseSReg = INVALID_SREG;
2151 sscanf(valName.c_str(), "v%d_", &baseSReg);
2152 res = cUnit->regLocation[baseSReg];
2153 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002154 }
2155 } else {
2156 res = it->second;
2157 }
2158 return res;
2159}
2160
2161Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2162{
2163 Instruction::Code res = Instruction::NOP;
2164 if (isWide) {
2165 switch(op) {
2166 case kOpAdd: res = Instruction::ADD_LONG; break;
2167 case kOpSub: res = Instruction::SUB_LONG; break;
2168 case kOpMul: res = Instruction::MUL_LONG; break;
2169 case kOpDiv: res = Instruction::DIV_LONG; break;
2170 case kOpRem: res = Instruction::REM_LONG; break;
2171 case kOpAnd: res = Instruction::AND_LONG; break;
2172 case kOpOr: res = Instruction::OR_LONG; break;
2173 case kOpXor: res = Instruction::XOR_LONG; break;
2174 case kOpLsl: res = Instruction::SHL_LONG; break;
2175 case kOpLsr: res = Instruction::USHR_LONG; break;
2176 case kOpAsr: res = Instruction::SHR_LONG; break;
2177 default: LOG(FATAL) << "Unexpected OpKind " << op;
2178 }
2179 } else if (isConst){
2180 switch(op) {
2181 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2182 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2183 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2184 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2185 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2186 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2187 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2188 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2189 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2190 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2191 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2192 default: LOG(FATAL) << "Unexpected OpKind " << op;
2193 }
2194 } else {
2195 switch(op) {
2196 case kOpAdd: res = Instruction::ADD_INT; break;
2197 case kOpSub: res = Instruction::SUB_INT; break;
2198 case kOpMul: res = Instruction::MUL_INT; break;
2199 case kOpDiv: res = Instruction::DIV_INT; break;
2200 case kOpRem: res = Instruction::REM_INT; break;
2201 case kOpAnd: res = Instruction::AND_INT; break;
2202 case kOpOr: res = Instruction::OR_INT; break;
2203 case kOpXor: res = Instruction::XOR_INT; break;
2204 case kOpLsl: res = Instruction::SHL_INT; break;
2205 case kOpLsr: res = Instruction::USHR_INT; break;
2206 case kOpAsr: res = Instruction::SHR_INT; break;
2207 default: LOG(FATAL) << "Unexpected OpKind " << op;
2208 }
2209 }
2210 return res;
2211}
2212
buzbee4f1181f2012-06-22 13:52:12 -07002213Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2214{
2215 Instruction::Code res = Instruction::NOP;
2216 if (isWide) {
2217 switch(op) {
2218 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2219 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2220 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2221 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2222 case kOpRem: res = Instruction::REM_DOUBLE; break;
2223 default: LOG(FATAL) << "Unexpected OpKind " << op;
2224 }
2225 } else {
2226 switch(op) {
2227 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2228 case kOpSub: res = Instruction::SUB_FLOAT; break;
2229 case kOpMul: res = Instruction::MUL_FLOAT; break;
2230 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2231 case kOpRem: res = Instruction::REM_FLOAT; break;
2232 default: LOG(FATAL) << "Unexpected OpKind " << op;
2233 }
2234 }
2235 return res;
2236}
2237
2238void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2239{
2240 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002241 /*
2242 * Normally, we won't ever generate an FP operation with an immediate
2243 * operand (not supported in Dex instruction set). However, the IR builder
2244 * may insert them - in particular for createNegFP. Recognize this case
2245 * and deal with it.
2246 */
2247 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2248 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2249 DCHECK(op2C == NULL);
2250 if ((op1C != NULL) && (op == kOpSub)) {
2251 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2252 if (rlDest.wide) {
2253 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2254 } else {
2255 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2256 }
buzbee4f1181f2012-06-22 13:52:12 -07002257 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002258 DCHECK(op1C == NULL);
2259 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2260 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2261 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2262 if (rlDest.wide) {
2263 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2264 } else {
2265 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2266 }
buzbee4f1181f2012-06-22 13:52:12 -07002267 }
2268}
2269
buzbee101305f2012-06-28 18:00:56 -07002270void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2271 Instruction::Code opcode)
2272{
2273 RegLocation rlDest = getLoc(cUnit, inst);
2274 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2275 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2276}
2277
buzbee76592632012-06-29 15:18:35 -07002278void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2279{
2280 RegLocation rlDest = getLoc(cUnit, inst);
2281 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2282 Instruction::Code opcode;
2283 if (rlDest.wide) {
2284 if (rlSrc.wide) {
2285 opcode = Instruction::LONG_TO_DOUBLE;
2286 } else {
2287 opcode = Instruction::INT_TO_DOUBLE;
2288 }
2289 } else {
2290 if (rlSrc.wide) {
2291 opcode = Instruction::LONG_TO_FLOAT;
2292 } else {
2293 opcode = Instruction::INT_TO_FLOAT;
2294 }
2295 }
2296 genConversion(cUnit, opcode, rlDest, rlSrc);
2297}
2298
TDYa1274ec8ccd2012-08-11 07:04:57 -07002299void cvtFPToInt(CompilationUnit* cUnit, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002300{
TDYa1274ec8ccd2012-08-11 07:04:57 -07002301 RegLocation rlDest = getLoc(cUnit, call_inst);
2302 RegLocation rlSrc = getLoc(cUnit, call_inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002303 Instruction::Code opcode;
2304 if (rlDest.wide) {
2305 if (rlSrc.wide) {
2306 opcode = Instruction::DOUBLE_TO_LONG;
2307 } else {
2308 opcode = Instruction::FLOAT_TO_LONG;
2309 }
2310 } else {
2311 if (rlSrc.wide) {
2312 opcode = Instruction::DOUBLE_TO_INT;
2313 } else {
2314 opcode = Instruction::FLOAT_TO_INT;
2315 }
2316 }
2317 genConversion(cUnit, opcode, rlDest, rlSrc);
2318}
2319
2320void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2321{
2322 RegLocation rlDest = getLoc(cUnit, inst);
2323 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2324 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2325}
2326
2327void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2328{
2329 RegLocation rlDest = getLoc(cUnit, inst);
2330 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2331 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2332 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2333 storeValue(cUnit, rlDest, rlSrc);
2334}
2335
2336void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2337{
2338 RegLocation rlDest = getLoc(cUnit, inst);
2339 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2340 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2341}
2342
2343
buzbee101305f2012-06-28 18:00:56 -07002344void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2345{
2346 // TODO: evaluate src/tgt types and add general support for more than int to long
2347 RegLocation rlDest = getLoc(cUnit, inst);
2348 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2349 DCHECK(rlDest.wide);
2350 DCHECK(!rlSrc.wide);
2351 DCHECK(!rlDest.fp);
2352 DCHECK(!rlSrc.fp);
2353 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2354 if (rlSrc.location == kLocPhysReg) {
2355 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2356 } else {
2357 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2358 }
2359 if (isSigned) {
2360 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2361 } else {
2362 loadConstant(cUnit, rlResult.highReg, 0);
2363 }
2364 storeValueWide(cUnit, rlDest, rlResult);
2365}
2366
buzbee2cfc6392012-05-07 14:51:40 -07002367void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2368{
2369 RegLocation rlDest = getLoc(cUnit, inst);
2370 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002371 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002372 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2373 if ((op == kOpSub) && (lhsImm != NULL)) {
2374 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002375 if (rlSrc1.wide) {
2376 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2377 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2378 } else {
2379 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2380 lhsImm->getSExtValue());
2381 }
buzbee4f1181f2012-06-22 13:52:12 -07002382 return;
2383 }
2384 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002385 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2386 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002387 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2388 if (!rlDest.wide && (constRhs != NULL)) {
buzbee2cfc6392012-05-07 14:51:40 -07002389 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
buzbee9a2487f2012-07-26 14:01:13 -07002390 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002391 } else {
2392 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002393 RegLocation rlSrc2;
2394 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002395 // ir_builder converts NOT_LONG to xor src, -1. Restore
2396 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2397 DCHECK_EQ(-1L, constRhs->getSExtValue());
2398 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002399 rlSrc2 = rlSrc1;
2400 } else {
2401 rlSrc2 = getLoc(cUnit, rhs);
2402 }
buzbee2cfc6392012-05-07 14:51:40 -07002403 if (rlDest.wide) {
2404 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2405 } else {
2406 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2407 }
2408 }
2409}
2410
buzbee2a83e8f2012-07-13 16:42:30 -07002411void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2412 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002413{
buzbee2a83e8f2012-07-13 16:42:30 -07002414 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2415 RegLocation rlDest = getLoc(cUnit, callInst);
2416 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2417 llvm::Value* rhs = callInst->getArgOperand(1);
2418 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2419 DCHECK(!rlDest.wide);
2420 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002421 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002422 RegLocation rlShift = getLoc(cUnit, rhs);
2423 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2424 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2425 } else {
2426 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2427 }
buzbee101305f2012-06-28 18:00:56 -07002428 }
2429}
2430
buzbee2cfc6392012-05-07 14:51:40 -07002431void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2432{
2433 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2434 DCHECK(brInst != NULL);
2435 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2436 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2437 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2438}
2439
2440void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2441{
2442 // Nop - these have already been processed
2443}
2444
2445void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2446{
2447 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2448 llvm::Value* retVal = retInst->getReturnValue();
2449 if (retVal != NULL) {
2450 RegLocation rlSrc = getLoc(cUnit, retVal);
2451 if (rlSrc.wide) {
2452 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2453 } else {
2454 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2455 }
2456 }
2457 genExitSequence(cUnit);
2458}
2459
2460ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2461{
2462 ConditionCode res = kCondAl;
2463 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002464 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002465 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2466 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2467 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002468 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002469 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002470 default: LOG(FATAL) << "Unexpected llvm condition";
2471 }
2472 return res;
2473}
2474
2475void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2476{
2477 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2478 UNIMPLEMENTED(FATAL);
2479}
2480
2481void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2482 llvm::BranchInst* brInst)
2483{
2484 // Get targets
2485 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2486 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2487 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2488 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2489 // Get comparison operands
2490 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2491 ConditionCode cond = getCond(iCmpInst->getPredicate());
2492 llvm::Value* lhs = iCmpInst->getOperand(0);
2493 // Not expecting a constant as 1st operand
2494 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2495 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2496 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2497 llvm::Value* rhs = inst->getOperand(1);
2498#if defined(TARGET_MIPS)
2499 // Compare and branch in one shot
2500 (void)taken;
2501 (void)cond;
2502 (void)rhs;
2503 UNIMPLEMENTED(FATAL);
2504#else
2505 //Compare, then branch
2506 // TODO: handle fused CMP_LONG/IF_xxZ case
2507 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2508 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002509 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2510 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002511 } else {
2512 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2513 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2514 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2515 }
2516 opCondBranch(cUnit, cond, taken);
2517#endif
2518 // Fallthrough
2519 opUnconditionalBranch(cUnit, fallThrough);
2520}
2521
2522void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2523 llvm::Function* callee)
2524{
2525 UNIMPLEMENTED(FATAL);
2526}
2527
buzbee2cfc6392012-05-07 14:51:40 -07002528void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2529{
buzbee4f1181f2012-06-22 13:52:12 -07002530 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002531 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2532 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002533 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2534 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002535 if (rlSrc.wide) {
2536 storeValueWide(cUnit, rlDest, rlSrc);
2537 } else {
2538 storeValue(cUnit, rlDest, rlSrc);
2539 }
2540}
2541
2542// Note: Immediate arg is a ConstantInt regardless of result type
2543void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2544{
buzbee4f1181f2012-06-22 13:52:12 -07002545 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002546 llvm::ConstantInt* src =
2547 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2548 uint64_t immval = src->getZExtValue();
2549 RegLocation rlDest = getLoc(cUnit, callInst);
2550 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2551 if (rlDest.wide) {
2552 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2553 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2554 storeValueWide(cUnit, rlDest, rlResult);
2555 } else {
2556 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2557 storeValue(cUnit, rlDest, rlResult);
2558 }
2559}
2560
buzbee101305f2012-06-28 18:00:56 -07002561void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2562 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002563{
buzbee4f1181f2012-06-22 13:52:12 -07002564 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002565 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002566 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002567 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002568 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002569 if (isString) {
2570 genConstString(cUnit, index, rlDest);
2571 } else {
2572 genConstClass(cUnit, index, rlDest);
2573 }
2574}
2575
2576void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2577{
2578 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2579 llvm::ConstantInt* offsetVal =
2580 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2581 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2582 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002583}
2584
buzbee4f1181f2012-06-22 13:52:12 -07002585void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2586{
buzbee32412962012-06-26 16:27:56 -07002587 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002588 llvm::ConstantInt* typeIdxVal =
2589 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2590 uint32_t typeIdx = typeIdxVal->getZExtValue();
2591 RegLocation rlDest = getLoc(cUnit, callInst);
2592 genNewInstance(cUnit, typeIdx, rlDest);
2593}
2594
buzbee8fa0fda2012-06-27 15:44:52 -07002595void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2596{
2597 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2598 llvm::ConstantInt* typeIdxVal =
2599 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2600 uint32_t typeIdx = typeIdxVal->getZExtValue();
2601 llvm::Value* len = callInst->getArgOperand(1);
2602 RegLocation rlLen = getLoc(cUnit, len);
2603 RegLocation rlDest = getLoc(cUnit, callInst);
2604 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2605}
2606
2607void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2608{
2609 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2610 llvm::ConstantInt* typeIdxVal =
2611 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2612 uint32_t typeIdx = typeIdxVal->getZExtValue();
2613 llvm::Value* src = callInst->getArgOperand(1);
2614 RegLocation rlSrc = getLoc(cUnit, src);
2615 RegLocation rlDest = getLoc(cUnit, callInst);
2616 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2617}
2618
buzbee32412962012-06-26 16:27:56 -07002619void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2620{
2621 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2622 llvm::Value* src = callInst->getArgOperand(0);
2623 RegLocation rlSrc = getLoc(cUnit, src);
2624 genThrow(cUnit, rlSrc);
2625}
2626
buzbee8fa0fda2012-06-27 15:44:52 -07002627void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2628 llvm::CallInst* callInst)
2629{
2630 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2631 llvm::ConstantInt* optFlags =
2632 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2633 llvm::Value* src = callInst->getArgOperand(1);
2634 RegLocation rlSrc = getLoc(cUnit, src);
2635 if (isEnter) {
2636 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2637 } else {
2638 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2639 }
2640}
2641
buzbee76592632012-06-29 15:18:35 -07002642void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002643{
2644 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2645 llvm::ConstantInt* optFlags =
2646 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2647 llvm::Value* src = callInst->getArgOperand(1);
2648 RegLocation rlSrc = getLoc(cUnit, src);
2649 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2650 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2651 RegLocation rlDest = getLoc(cUnit, callInst);
2652 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2653 int lenOffset = Array::LengthOffset().Int32Value();
2654 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2655 storeValue(cUnit, rlDest, rlResult);
2656}
2657
buzbee32412962012-06-26 16:27:56 -07002658void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2659{
2660 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
2661 int exOffset = Thread::ExceptionOffset().Int32Value();
2662 RegLocation rlDest = getLoc(cUnit, callInst);
2663 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2664#if defined(TARGET_X86)
2665 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
2666 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
2667#else
2668 int resetReg = oatAllocTemp(cUnit);
2669 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
2670 loadConstant(cUnit, resetReg, 0);
2671 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
2672 oatFreeTemp(cUnit, resetReg);
2673#endif
2674 storeValue(cUnit, rlDest, rlResult);
2675}
2676
buzbee4f1181f2012-06-22 13:52:12 -07002677void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2678 bool isObject)
2679{
buzbee32412962012-06-26 16:27:56 -07002680 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002681 llvm::ConstantInt* typeIdxVal =
2682 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2683 uint32_t typeIdx = typeIdxVal->getZExtValue();
2684 RegLocation rlDest = getLoc(cUnit, callInst);
2685 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2686}
2687
buzbee8fa0fda2012-06-27 15:44:52 -07002688void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2689 bool isObject)
2690{
2691 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2692 llvm::ConstantInt* typeIdxVal =
2693 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2694 uint32_t typeIdx = typeIdxVal->getZExtValue();
2695 llvm::Value* src = callInst->getArgOperand(1);
2696 RegLocation rlSrc = getLoc(cUnit, src);
2697 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2698}
2699
2700void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2701 int scale)
2702{
2703 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2704 llvm::ConstantInt* optFlags =
2705 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2706 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2707 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2708 RegLocation rlDest = getLoc(cUnit, callInst);
2709 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2710 rlDest, scale);
2711}
2712
2713void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002714 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002715{
2716 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2717 llvm::ConstantInt* optFlags =
2718 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2719 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2720 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2721 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002722 if (isObject) {
2723 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2724 rlSrc, scale);
2725 } else {
2726 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2727 rlSrc, scale);
2728 }
2729}
2730
2731void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2732{
2733 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2734}
2735
2736void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2737 OpSize size, int scale)
2738{
2739 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002740}
2741
buzbee101305f2012-06-28 18:00:56 -07002742void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2743 bool isWide, bool isObj)
2744{
2745 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2746 llvm::ConstantInt* optFlags =
2747 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2748 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2749 llvm::ConstantInt* fieldIdx =
2750 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2751 RegLocation rlDest = getLoc(cUnit, callInst);
2752 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2753 size, rlDest, rlObj, isWide, isObj);
2754}
2755
2756void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2757 bool isWide, bool isObj)
2758{
2759 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2760 llvm::ConstantInt* optFlags =
2761 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2762 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2763 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2764 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002765 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002766 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2767 size, rlSrc, rlObj, isWide, isObj);
2768}
2769
2770void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2771{
2772 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2773 llvm::ConstantInt* typeIdx =
2774 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2775 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2776 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2777}
2778
buzbee76592632012-06-29 15:18:35 -07002779void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2780 Instruction::Code opcode)
2781{
2782 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2783 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2784 RegLocation rlDest = getLoc(cUnit, callInst);
2785 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2786}
2787
2788void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2789{
2790 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2791 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2792 RegLocation rlDest = getLoc(cUnit, callInst);
2793 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2794}
2795
buzbeef58c12c2012-07-03 15:06:29 -07002796void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2797{
2798 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2799 DCHECK(swInst != NULL);
2800 llvm::Value* testVal = swInst->getCondition();
2801 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2802 DCHECK(tableOffsetNode != NULL);
2803 llvm::ConstantInt* tableOffsetValue =
2804 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2805 int32_t tableOffset = tableOffsetValue->getSExtValue();
2806 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeea1da8a52012-07-09 14:00:21 -07002807 const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2808 u2 tableMagic = *table;
2809 if (tableMagic == 0x100) {
2810 genPackedSwitch(cUnit, tableOffset, rlSrc);
2811 } else {
2812 DCHECK_EQ(tableMagic, 0x200);
2813 genSparseSwitch(cUnit, tableOffset, rlSrc);
2814 }
buzbeef58c12c2012-07-03 15:06:29 -07002815}
2816
buzbee6969d502012-06-15 16:40:31 -07002817void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002818 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002819{
2820 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2821 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002822 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002823 info->result.location = kLocInvalid;
2824 } else {
2825 info->result = getLoc(cUnit, callInst);
2826 }
2827 llvm::ConstantInt* invokeTypeVal =
2828 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2829 llvm::ConstantInt* methodIndexVal =
2830 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2831 llvm::ConstantInt* optFlagsVal =
2832 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2833 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2834 info->index = methodIndexVal->getZExtValue();
2835 info->optFlags = optFlagsVal->getZExtValue();
2836 info->offset = cUnit->currentDalvikOffset;
2837
buzbee6969d502012-06-15 16:40:31 -07002838 // Count the argument words, and then build argument array.
2839 info->numArgWords = 0;
2840 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2841 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2842 info->numArgWords += tLoc.wide ? 2 : 1;
2843 }
2844 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2845 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2846 // Now, fill in the location records, synthesizing high loc of wide vals
2847 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002848 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002849 if (info->args[next].wide) {
2850 next++;
2851 // TODO: Might make sense to mark this as an invalid loc
2852 info->args[next].origSReg = info->args[next-1].origSReg+1;
2853 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2854 }
2855 next++;
2856 }
buzbee4f4dfc72012-07-02 14:54:44 -07002857 // TODO - rework such that we no longer need isRange
2858 info->isRange = (info->numArgWords > 5);
2859
buzbee76592632012-06-29 15:18:35 -07002860 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002861 genFilledNewArray(cUnit, info);
2862 } else {
2863 genInvoke(cUnit, info);
2864 }
buzbee6969d502012-06-15 16:40:31 -07002865}
2866
buzbeead8f15e2012-06-18 14:49:45 -07002867/* Look up the RegLocation associated with a Value. Must already be defined */
2868RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2869{
2870 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2871 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2872 return it->second;
2873}
2874
buzbee2cfc6392012-05-07 14:51:40 -07002875bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2876{
buzbee0967a252012-09-14 10:43:54 -07002877 while (cUnit->llvmBlocks.find(bb) == cUnit->llvmBlocks.end()) {
2878 llvm::BasicBlock* nextBB = NULL;
2879 cUnit->llvmBlocks.insert(bb);
2880 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2881 // Define the starting label
2882 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2883 // Extract the type and starting offset from the block's name
2884 char blockType = kNormalBlock;
2885 if (!isEntry) {
2886 const char* blockName = bb->getName().str().c_str();
2887 int dummy;
2888 sscanf(blockName, kLabelFormat, &blockType, &blockLabel->operands[0], &dummy);
2889 cUnit->currentDalvikOffset = blockLabel->operands[0];
2890 } else {
2891 cUnit->currentDalvikOffset = 0;
2892 }
2893 // Set the label kind
2894 blockLabel->opcode = kPseudoNormalBlockLabel;
2895 // Insert the label
2896 oatAppendLIR(cUnit, blockLabel);
buzbee2cfc6392012-05-07 14:51:40 -07002897
buzbee0967a252012-09-14 10:43:54 -07002898 LIR* headLIR = NULL;
buzbee8320f382012-09-11 16:29:42 -07002899
buzbee0967a252012-09-14 10:43:54 -07002900 if (blockType == kCatchBlock) {
2901 headLIR = newLIR0(cUnit, kPseudoSafepointPC);
2902 }
buzbee8320f382012-09-11 16:29:42 -07002903
buzbee0967a252012-09-14 10:43:54 -07002904 // Free temp registers and reset redundant store tracking */
2905 oatResetRegPool(cUnit);
2906 oatResetDefTracking(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002907
buzbee0967a252012-09-14 10:43:54 -07002908 //TODO: restore oat incoming liveness optimization
2909 oatClobberAllRegs(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002910
buzbee0967a252012-09-14 10:43:54 -07002911 if (isEntry) {
2912 RegLocation* argLocs = (RegLocation*)
2913 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2914 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2915 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2916 // Skip past Method*
2917 it++;
2918 for (unsigned i = 0; it != it_end; ++it) {
2919 llvm::Value* val = it;
2920 argLocs[i++] = valToLoc(cUnit, val);
2921 llvm::Type* ty = val->getType();
2922 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2923 argLocs[i] = argLocs[i-1];
2924 argLocs[i].lowReg = argLocs[i].highReg;
2925 argLocs[i].origSReg++;
2926 argLocs[i].sRegLow = INVALID_SREG;
2927 argLocs[i].highWord = true;
2928 i++;
2929 }
2930 }
2931 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
2932 }
2933
2934 // Visit all of the instructions in the block
2935 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2936 llvm::Instruction* inst = it;
2937 llvm::BasicBlock::iterator nextIt = ++it;
2938 // Extract the Dalvik offset from the instruction
2939 uint32_t opcode = inst->getOpcode();
2940 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2941 if (dexOffsetNode != NULL) {
2942 llvm::ConstantInt* dexOffsetValue =
2943 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2944 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2945 }
2946
2947 oatResetRegPool(cUnit);
2948 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2949 oatClobberAllRegs(cUnit);
2950 }
2951
2952 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2953 oatResetDefTracking(cUnit);
2954 }
2955
2956 #ifndef NDEBUG
2957 /* Reset temp tracking sanity check */
2958 cUnit->liveSReg = INVALID_SREG;
2959 #endif
2960
2961 // TODO: use llvm opcode name here instead of "boundary" if verbose
2962 LIR* boundaryLIR = markBoundary(cUnit, cUnit->currentDalvikOffset, "boundary");
2963
2964 /* Remember the first LIR for thisl block*/
2965 if (headLIR == NULL) {
2966 headLIR = boundaryLIR;
2967 headLIR->defMask = ENCODE_ALL;
2968 }
2969
2970 switch(opcode) {
2971
2972 case llvm::Instruction::ICmp: {
2973 llvm::Instruction* nextInst = nextIt;
2974 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2975 if (brInst != NULL /* and... */) {
2976 cvtICmpBr(cUnit, inst, brInst);
2977 ++it;
2978 } else {
2979 cvtICmp(cUnit, inst);
2980 }
2981 }
2982 break;
2983
2984 case llvm::Instruction::Call: {
2985 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2986 llvm::Function* callee = callInst->getCalledFunction();
2987 greenland::IntrinsicHelper::IntrinsicId id =
2988 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2989 switch (id) {
2990 case greenland::IntrinsicHelper::AllocaShadowFrame:
2991 case greenland::IntrinsicHelper::SetShadowFrameEntry:
2992 case greenland::IntrinsicHelper::PopShadowFrame:
2993 // Ignore shadow frame stuff for quick compiler
2994 break;
2995 case greenland::IntrinsicHelper::CopyInt:
2996 case greenland::IntrinsicHelper::CopyObj:
2997 case greenland::IntrinsicHelper::CopyFloat:
2998 case greenland::IntrinsicHelper::CopyLong:
2999 case greenland::IntrinsicHelper::CopyDouble:
3000 cvtCopy(cUnit, callInst);
3001 break;
3002 case greenland::IntrinsicHelper::ConstInt:
3003 case greenland::IntrinsicHelper::ConstObj:
3004 case greenland::IntrinsicHelper::ConstLong:
3005 case greenland::IntrinsicHelper::ConstFloat:
3006 case greenland::IntrinsicHelper::ConstDouble:
3007 cvtConst(cUnit, callInst);
3008 break;
3009 case greenland::IntrinsicHelper::DivInt:
3010 case greenland::IntrinsicHelper::DivLong:
3011 cvtBinOp(cUnit, kOpDiv, inst);
3012 break;
3013 case greenland::IntrinsicHelper::RemInt:
3014 case greenland::IntrinsicHelper::RemLong:
3015 cvtBinOp(cUnit, kOpRem, inst);
3016 break;
3017 case greenland::IntrinsicHelper::MethodInfo:
3018 // Already dealt with - just ignore it here.
3019 break;
3020 case greenland::IntrinsicHelper::CheckSuspend:
3021 genSuspendTest(cUnit, 0 /* optFlags already applied */);
3022 break;
3023 case greenland::IntrinsicHelper::HLInvokeObj:
3024 case greenland::IntrinsicHelper::HLInvokeFloat:
3025 case greenland::IntrinsicHelper::HLInvokeDouble:
3026 case greenland::IntrinsicHelper::HLInvokeLong:
3027 case greenland::IntrinsicHelper::HLInvokeInt:
3028 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
3029 break;
3030 case greenland::IntrinsicHelper::HLInvokeVoid:
3031 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
3032 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003033 case greenland::IntrinsicHelper::HLFilledNewArray:
buzbee0967a252012-09-14 10:43:54 -07003034 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
3035 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003036 case greenland::IntrinsicHelper::HLFillArrayData:
buzbee0967a252012-09-14 10:43:54 -07003037 cvtFillArrayData(cUnit, callInst);
3038 break;
3039 case greenland::IntrinsicHelper::ConstString:
3040 cvtConstObject(cUnit, callInst, true /* isString */);
3041 break;
3042 case greenland::IntrinsicHelper::ConstClass:
3043 cvtConstObject(cUnit, callInst, false /* isString */);
3044 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003045 case greenland::IntrinsicHelper::HLCheckCast:
buzbee0967a252012-09-14 10:43:54 -07003046 cvtCheckCast(cUnit, callInst);
3047 break;
3048 case greenland::IntrinsicHelper::NewInstance:
3049 cvtNewInstance(cUnit, callInst);
3050 break;
3051 case greenland::IntrinsicHelper::HLSgetObject:
3052 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
3053 break;
3054 case greenland::IntrinsicHelper::HLSget:
3055 case greenland::IntrinsicHelper::HLSgetFloat:
3056 case greenland::IntrinsicHelper::HLSgetBoolean:
3057 case greenland::IntrinsicHelper::HLSgetByte:
3058 case greenland::IntrinsicHelper::HLSgetChar:
3059 case greenland::IntrinsicHelper::HLSgetShort:
3060 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
3061 break;
3062 case greenland::IntrinsicHelper::HLSgetWide:
3063 case greenland::IntrinsicHelper::HLSgetDouble:
3064 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
3065 break;
3066 case greenland::IntrinsicHelper::HLSput:
3067 case greenland::IntrinsicHelper::HLSputFloat:
3068 case greenland::IntrinsicHelper::HLSputBoolean:
3069 case greenland::IntrinsicHelper::HLSputByte:
3070 case greenland::IntrinsicHelper::HLSputChar:
3071 case greenland::IntrinsicHelper::HLSputShort:
3072 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
3073 break;
3074 case greenland::IntrinsicHelper::HLSputWide:
3075 case greenland::IntrinsicHelper::HLSputDouble:
3076 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
3077 break;
3078 case greenland::IntrinsicHelper::HLSputObject:
3079 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
3080 break;
3081 case greenland::IntrinsicHelper::GetException:
3082 cvtMoveException(cUnit, callInst);
3083 break;
TDYa127f71bf5a2012-07-29 20:09:52 -07003084 case greenland::IntrinsicHelper::HLThrowException:
buzbee0967a252012-09-14 10:43:54 -07003085 cvtThrow(cUnit, callInst);
3086 break;
3087 case greenland::IntrinsicHelper::MonitorEnter:
3088 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
3089 break;
3090 case greenland::IntrinsicHelper::MonitorExit:
3091 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
3092 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003093 case greenland::IntrinsicHelper::OptArrayLength:
buzbee0967a252012-09-14 10:43:54 -07003094 cvtArrayLength(cUnit, callInst);
3095 break;
3096 case greenland::IntrinsicHelper::NewArray:
3097 cvtNewArray(cUnit, callInst);
3098 break;
3099 case greenland::IntrinsicHelper::InstanceOf:
3100 cvtInstanceOf(cUnit, callInst);
3101 break;
3102
3103 case greenland::IntrinsicHelper::HLArrayGet:
3104 case greenland::IntrinsicHelper::HLArrayGetObject:
3105 case greenland::IntrinsicHelper::HLArrayGetFloat:
3106 cvtAget(cUnit, callInst, kWord, 2);
3107 break;
3108 case greenland::IntrinsicHelper::HLArrayGetWide:
3109 case greenland::IntrinsicHelper::HLArrayGetDouble:
3110 cvtAget(cUnit, callInst, kLong, 3);
3111 break;
3112 case greenland::IntrinsicHelper::HLArrayGetBoolean:
3113 cvtAget(cUnit, callInst, kUnsignedByte, 0);
3114 break;
3115 case greenland::IntrinsicHelper::HLArrayGetByte:
3116 cvtAget(cUnit, callInst, kSignedByte, 0);
3117 break;
3118 case greenland::IntrinsicHelper::HLArrayGetChar:
3119 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
3120 break;
3121 case greenland::IntrinsicHelper::HLArrayGetShort:
3122 cvtAget(cUnit, callInst, kSignedHalf, 1);
3123 break;
3124
3125 case greenland::IntrinsicHelper::HLArrayPut:
3126 case greenland::IntrinsicHelper::HLArrayPutFloat:
3127 cvtAputPrimitive(cUnit, callInst, kWord, 2);
3128 break;
3129 case greenland::IntrinsicHelper::HLArrayPutObject:
3130 cvtAputObj(cUnit, callInst);
3131 break;
3132 case greenland::IntrinsicHelper::HLArrayPutWide:
3133 case greenland::IntrinsicHelper::HLArrayPutDouble:
3134 cvtAputPrimitive(cUnit, callInst, kLong, 3);
3135 break;
3136 case greenland::IntrinsicHelper::HLArrayPutBoolean:
3137 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
3138 break;
3139 case greenland::IntrinsicHelper::HLArrayPutByte:
3140 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
3141 break;
3142 case greenland::IntrinsicHelper::HLArrayPutChar:
3143 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
3144 break;
3145 case greenland::IntrinsicHelper::HLArrayPutShort:
3146 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
3147 break;
3148
3149 case greenland::IntrinsicHelper::HLIGet:
3150 case greenland::IntrinsicHelper::HLIGetFloat:
3151 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3152 break;
3153 case greenland::IntrinsicHelper::HLIGetObject:
3154 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3155 break;
3156 case greenland::IntrinsicHelper::HLIGetWide:
3157 case greenland::IntrinsicHelper::HLIGetDouble:
3158 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3159 break;
3160 case greenland::IntrinsicHelper::HLIGetBoolean:
3161 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3162 false /* obj */);
3163 break;
3164 case greenland::IntrinsicHelper::HLIGetByte:
3165 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3166 false /* obj */);
3167 break;
3168 case greenland::IntrinsicHelper::HLIGetChar:
3169 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3170 false /* obj */);
3171 break;
3172 case greenland::IntrinsicHelper::HLIGetShort:
3173 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3174 false /* obj */);
3175 break;
3176
3177 case greenland::IntrinsicHelper::HLIPut:
3178 case greenland::IntrinsicHelper::HLIPutFloat:
3179 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3180 break;
3181 case greenland::IntrinsicHelper::HLIPutObject:
3182 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3183 break;
3184 case greenland::IntrinsicHelper::HLIPutWide:
3185 case greenland::IntrinsicHelper::HLIPutDouble:
3186 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3187 break;
3188 case greenland::IntrinsicHelper::HLIPutBoolean:
3189 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3190 false /* obj */);
3191 break;
3192 case greenland::IntrinsicHelper::HLIPutByte:
3193 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3194 false /* obj */);
3195 break;
3196 case greenland::IntrinsicHelper::HLIPutChar:
3197 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3198 false /* obj */);
3199 break;
3200 case greenland::IntrinsicHelper::HLIPutShort:
3201 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3202 false /* obj */);
3203 break;
3204
3205 case greenland::IntrinsicHelper::IntToChar:
3206 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3207 break;
3208 case greenland::IntrinsicHelper::IntToShort:
3209 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3210 break;
3211 case greenland::IntrinsicHelper::IntToByte:
3212 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3213 break;
3214
TDYa1274ec8ccd2012-08-11 07:04:57 -07003215 case greenland::IntrinsicHelper::F2I:
3216 case greenland::IntrinsicHelper::D2I:
3217 case greenland::IntrinsicHelper::F2L:
3218 case greenland::IntrinsicHelper::D2L:
3219 cvtFPToInt(cUnit, callInst);
3220 break;
3221
buzbee0967a252012-09-14 10:43:54 -07003222 case greenland::IntrinsicHelper::CmplFloat:
3223 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3224 break;
3225 case greenland::IntrinsicHelper::CmpgFloat:
3226 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3227 break;
3228 case greenland::IntrinsicHelper::CmplDouble:
3229 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3230 break;
3231 case greenland::IntrinsicHelper::CmpgDouble:
3232 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3233 break;
3234
3235 case greenland::IntrinsicHelper::CmpLong:
3236 cvtLongCompare(cUnit, callInst);
3237 break;
3238
3239 case greenland::IntrinsicHelper::SHLLong:
3240 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
3241 break;
3242 case greenland::IntrinsicHelper::SHRLong:
3243 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3244 break;
3245 case greenland::IntrinsicHelper::USHRLong:
3246 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3247 break;
3248 case greenland::IntrinsicHelper::SHLInt:
3249 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3250 break;
3251 case greenland::IntrinsicHelper::SHRInt:
3252 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3253 break;
3254 case greenland::IntrinsicHelper::USHRInt:
3255 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3256 break;
3257
3258 case greenland::IntrinsicHelper::CatchTargets: {
3259 llvm::SwitchInst* swInst =
3260 llvm::dyn_cast<llvm::SwitchInst>(nextIt);
3261 DCHECK(swInst != NULL);
3262 /*
3263 * Discard the edges and the following conditional branch.
3264 * Do a direct branch to the default target (which is the
3265 * "work" portion of the pair.
3266 * TODO: awful code layout - rework
3267 */
3268 llvm::BasicBlock* targetBB = swInst->getDefaultDest();
3269 DCHECK(targetBB != NULL);
3270 opUnconditionalBranch(cUnit,
3271 cUnit->blockToLabelMap.Get(targetBB));
3272 ++it;
3273 // Set next bb to default target - improves code layout
3274 nextBB = targetBB;
3275 }
3276 break;
3277
3278 default:
3279 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3280 << cUnit->intrinsic_helper->GetName(id);
3281 }
3282 }
3283 break;
3284
3285 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3286 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3287 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3288 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3289 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3290 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3291 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3292 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3293 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
3294 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3295 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
3296 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3297 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3298 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3299 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3300 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
3301 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003302 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3303 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3304 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
3305
3306 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3307 break;
3308 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3309 break;
3310
3311 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3312
3313 case llvm::Instruction::Unreachable:
3314 break; // FIXME: can we really ignore these?
3315
3316 case llvm::Instruction::Shl:
3317 case llvm::Instruction::LShr:
3318 case llvm::Instruction::AShr:
3319 case llvm::Instruction::Invoke:
3320 case llvm::Instruction::FPToUI:
TDYa1274ec8ccd2012-08-11 07:04:57 -07003321 case llvm::Instruction::FPToSI:
buzbee0967a252012-09-14 10:43:54 -07003322 case llvm::Instruction::UIToFP:
3323 case llvm::Instruction::PtrToInt:
3324 case llvm::Instruction::IntToPtr:
3325 case llvm::Instruction::FCmp:
3326 case llvm::Instruction::URem:
3327 case llvm::Instruction::UDiv:
3328 case llvm::Instruction::Resume:
3329 case llvm::Instruction::Alloca:
3330 case llvm::Instruction::GetElementPtr:
3331 case llvm::Instruction::Fence:
3332 case llvm::Instruction::AtomicCmpXchg:
3333 case llvm::Instruction::AtomicRMW:
3334 case llvm::Instruction::BitCast:
3335 case llvm::Instruction::VAArg:
3336 case llvm::Instruction::Select:
3337 case llvm::Instruction::UserOp1:
3338 case llvm::Instruction::UserOp2:
3339 case llvm::Instruction::ExtractElement:
3340 case llvm::Instruction::InsertElement:
3341 case llvm::Instruction::ShuffleVector:
3342 case llvm::Instruction::ExtractValue:
3343 case llvm::Instruction::InsertValue:
3344 case llvm::Instruction::LandingPad:
3345 case llvm::Instruction::IndirectBr:
3346 case llvm::Instruction::Load:
3347 case llvm::Instruction::Store:
3348 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3349
3350 default:
3351 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3352 break;
buzbeead8f15e2012-06-18 14:49:45 -07003353 }
3354 }
buzbee2cfc6392012-05-07 14:51:40 -07003355
buzbee0967a252012-09-14 10:43:54 -07003356 if (headLIR != NULL) {
3357 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
buzbee2cfc6392012-05-07 14:51:40 -07003358 }
buzbee0967a252012-09-14 10:43:54 -07003359 if (nextBB != NULL) {
3360 bb = nextBB;
3361 nextBB = NULL;
buzbee6969d502012-06-15 16:40:31 -07003362 }
buzbee6969d502012-06-15 16:40:31 -07003363 }
buzbee2cfc6392012-05-07 14:51:40 -07003364 return false;
3365}
3366
3367/*
3368 * Convert LLVM_IR to MIR:
3369 * o Iterate through the LLVM_IR and construct a graph using
3370 * standard MIR building blocks.
3371 * o Perform a basic-block optimization pass to remove unnecessary
3372 * store/load sequences.
3373 * o Convert the LLVM Value operands into RegLocations where applicable.
3374 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3375 * o Perform register promotion
3376 * o Iterate through the graph a basic block at a time, generating
3377 * LIR.
3378 * o Assemble LIR as usual.
3379 * o Profit.
3380 */
3381void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3382{
buzbeead8f15e2012-06-18 14:49:45 -07003383 llvm::Function* func = cUnit->func;
3384 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003385 // Allocate a list for LIR basic block labels
3386 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07003387 (LIR*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3388 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003389 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003390 for (llvm::Function::iterator i = func->begin(),
3391 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003392 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3393 &labelList[nextLabel++]);
3394 }
buzbeead8f15e2012-06-18 14:49:45 -07003395
3396 /*
3397 * Keep honest - clear regLocations, Value => RegLocation,
3398 * promotion map and VmapTables.
3399 */
3400 cUnit->locMap.clear(); // Start fresh
3401 cUnit->regLocation = NULL;
3402 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3403 i++) {
3404 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3405 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3406 }
3407 cUnit->coreSpillMask = 0;
3408 cUnit->numCoreSpills = 0;
3409 cUnit->fpSpillMask = 0;
3410 cUnit->numFPSpills = 0;
3411 cUnit->coreVmapTable.clear();
3412 cUnit->fpVmapTable.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003413
3414 /*
3415 * At this point, we've lost all knowledge of register promotion.
3416 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003417 * exists - not required for correctness). Normally, this will
3418 * be the first instruction we encounter, so we won't have to iterate
3419 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003420 */
buzbeeca7a5e42012-08-20 11:12:18 -07003421 for (llvm::inst_iterator i = llvm::inst_begin(func),
3422 e = llvm::inst_end(func); i != e; ++i) {
3423 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(&*i);
3424 if (callInst != NULL) {
3425 llvm::Function* callee = callInst->getCalledFunction();
3426 greenland::IntrinsicHelper::IntrinsicId id =
3427 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3428 if (id == greenland::IntrinsicHelper::MethodInfo) {
3429 if (cUnit->printMe) {
3430 LOG(INFO) << "Found MethodInfo";
3431 }
3432 llvm::MDNode* regInfoNode = callInst->getMetadata("RegInfo");
3433 if (regInfoNode != NULL) {
3434 llvm::ConstantInt* numInsValue =
3435 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(0));
3436 llvm::ConstantInt* numRegsValue =
3437 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(1));
3438 llvm::ConstantInt* numOutsValue =
3439 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(2));
3440 llvm::ConstantInt* numCompilerTempsValue =
3441 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(3));
3442 llvm::ConstantInt* numSSARegsValue =
3443 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(4));
3444 if (cUnit->printMe) {
3445 LOG(INFO) << "RegInfo - Ins:" << numInsValue->getZExtValue()
3446 << ", Regs:" << numRegsValue->getZExtValue()
3447 << ", Outs:" << numOutsValue->getZExtValue()
3448 << ", CTemps:" << numCompilerTempsValue->getZExtValue()
3449 << ", SSARegs:" << numSSARegsValue->getZExtValue();
3450 }
3451 }
3452 llvm::MDNode* pmapInfoNode = callInst->getMetadata("PromotionMap");
3453 if (pmapInfoNode != NULL) {
3454 int elems = pmapInfoNode->getNumOperands();
3455 if (cUnit->printMe) {
3456 LOG(INFO) << "PMap size: " << elems;
3457 }
3458 for (int i = 0; i < elems; i++) {
3459 llvm::ConstantInt* rawMapData =
3460 static_cast<llvm::ConstantInt*>(pmapInfoNode->getOperand(i));
3461 uint32_t mapData = rawMapData->getZExtValue();
3462 PromotionMap* p = &cUnit->promotionMap[i];
3463 p->firstInPair = (mapData >> 24) & 0xff;
3464 p->fpReg = (mapData >> 16) & 0xff;
3465 p->coreReg = (mapData >> 8) & 0xff;
3466 p->fpLocation = static_cast<RegLocationType>((mapData >> 4) & 0xf);
3467 if (p->fpLocation == kLocPhysReg) {
3468 oatRecordFpPromotion(cUnit, p->fpReg, i);
3469 }
3470 p->coreLocation = static_cast<RegLocationType>(mapData & 0xf);
3471 if (p->coreLocation == kLocPhysReg) {
3472 oatRecordCorePromotion(cUnit, p->coreReg, i);
3473 }
3474 }
3475 if (cUnit->printMe) {
3476 oatDumpPromotionMap(cUnit);
3477 }
3478 }
3479 break;
3480 }
3481 }
3482 }
3483 oatAdjustSpillMask(cUnit);
3484 cUnit->frameSize = oatComputeFrameSize(cUnit);
buzbeead8f15e2012-06-18 14:49:45 -07003485
3486 // Create RegLocations for arguments
3487 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3488 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3489 for (; it != it_end; ++it) {
3490 llvm::Value* val = it;
3491 createLocFromValue(cUnit, val);
3492 }
3493 // Create RegLocations for all non-argument defintions
3494 for (llvm::inst_iterator i = llvm::inst_begin(func),
3495 e = llvm::inst_end(func); i != e; ++i) {
3496 llvm::Value* val = &*i;
3497 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3498 createLocFromValue(cUnit, val);
3499 }
3500 }
3501
buzbee2cfc6392012-05-07 14:51:40 -07003502 // Walk the blocks, generating code.
3503 for (llvm::Function::iterator i = cUnit->func->begin(),
3504 e = cUnit->func->end(); i != e; ++i) {
3505 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3506 }
3507
3508 handleSuspendLaunchpads(cUnit);
3509
3510 handleThrowLaunchpads(cUnit);
3511
3512 handleIntrinsicLaunchpads(cUnit);
3513
buzbee692be802012-08-29 15:52:59 -07003514 cUnit->func->eraseFromParent();
3515 cUnit->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003516}
3517
3518
3519} // namespace art
3520
3521#endif // ART_USE_QUICK_COMPILER