blob: c176c4e10b945f685e8d44386ebab693e09f40f4 [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 Liao21d28f52012-06-12 05:55:00 -07001780 if (llvmBB != NULL) {
1781 cUnit->irb->SetInsertPoint(llvmBB);
1782 setDexOffset(cUnit, bb->startOffset);
1783 }
buzbee2cfc6392012-05-07 14:51:40 -07001784
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001785 if (cUnit->printMe) {
1786 LOG(INFO) << "................................";
1787 LOG(INFO) << "Block id " << bb->id;
1788 if (llvmBB != NULL) {
1789 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1790 } else {
1791 LOG(INFO) << "llvmBB is NULL";
1792 }
1793 }
1794
buzbee2cfc6392012-05-07 14:51:40 -07001795 if (bb->blockType == kEntryBlock) {
1796 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001797 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1798 cUnit->numDalvikRegisters, true,
1799 kAllocMisc);
1800 for (int i = 0; i < cUnit->numSSARegs; i++) {
1801 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1802 }
1803 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1804 if (canBeRef[i]) {
1805 cUnit->numShadowFrameEntries++;
1806 }
1807 }
1808 if (cUnit->numShadowFrameEntries > 0) {
1809 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1810 cUnit->numShadowFrameEntries, true,
1811 kAllocMisc);
1812 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1813 if (canBeRef[i]) {
1814 cUnit->shadowMap[j++] = i;
1815 }
1816 }
buzbeeb03f4872012-06-11 15:22:11 -07001817 }
Shih-wei Liao569daf12012-08-10 23:22:33 -07001818 greenland::IntrinsicHelper::IntrinsicId id =
1819 greenland::IntrinsicHelper::AllocaShadowFrame;
1820 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1821 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1822 cUnit->irb->CreateCall(func, entries);
buzbee2cfc6392012-05-07 14:51:40 -07001823 } else if (bb->blockType == kExitBlock) {
1824 /*
1825 * Because of the differences between how MIR/LIR and llvm handle exit
1826 * blocks, we won't explicitly covert them. On the llvm-to-lir
1827 * path, it will need to be regenereated.
1828 */
1829 return false;
buzbee6969d502012-06-15 16:40:31 -07001830 } else if (bb->blockType == kExceptionHandling) {
1831 /*
1832 * Because we're deferring null checking, delete the associated empty
1833 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001834 */
1835 llvmBB->eraseFromParent();
1836 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001837 }
1838
1839 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1840
1841 setDexOffset(cUnit, mir->offset);
1842
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001843 int opcode = mir->dalvikInsn.opcode;
1844 Instruction::Format dalvikFormat =
1845 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001846
1847 /* If we're compiling for the debugger, generate an update callout */
1848 if (cUnit->genDebugger) {
1849 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1850 //genDebuggerUpdate(cUnit, mir->offset);
1851 }
1852
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001853 if (opcode == kMirOpCheck) {
1854 // Combine check and work halves of throwing instruction.
1855 MIR* workHalf = mir->meta.throwInsn;
1856 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
1857 opcode = mir->dalvikInsn.opcode;
1858 SSARepresentation* ssaRep = workHalf->ssaRep;
1859 workHalf->ssaRep = mir->ssaRep;
1860 mir->ssaRep = ssaRep;
1861 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1862 if (bb->successorBlockList.blockListType == kCatch) {
1863 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
1864 greenland::IntrinsicHelper::CatchTargets);
1865 llvm::Value* switchKey =
1866 cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
1867 GrowableListIterator iter;
1868 oatGrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
1869 // New basic block to use for work half
1870 llvm::BasicBlock* workBB =
1871 llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
1872 llvm::SwitchInst* sw =
1873 cUnit->irb->CreateSwitch(switchKey, workBB,
1874 bb->successorBlockList.blocks.numUsed);
1875 while (true) {
1876 SuccessorBlockInfo *successorBlockInfo =
1877 (SuccessorBlockInfo *) oatGrowableListIteratorNext(&iter);
1878 if (successorBlockInfo == NULL) break;
1879 llvm::BasicBlock *target =
1880 getLLVMBlock(cUnit, successorBlockInfo->block->id);
1881 int typeIndex = successorBlockInfo->key;
1882 sw->addCase(cUnit->irb->getInt32(typeIndex), target);
1883 }
1884 llvmBB = workBB;
1885 cUnit->irb->SetInsertPoint(llvmBB);
1886 }
1887 }
1888
1889 if (opcode >= kMirOpFirst) {
buzbee2cfc6392012-05-07 14:51:40 -07001890 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1891 continue;
1892 }
1893
1894 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1895 NULL /* labelList */);
1896 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001897 Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001898 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001899 mir->offset, opcode,
buzbee2cfc6392012-05-07 14:51:40 -07001900 Instruction::Name(dalvikOpcode),
1901 dalvikFormat);
1902 }
1903 }
1904
buzbee4be777b2012-07-12 14:38:18 -07001905 if (bb->blockType == kEntryBlock) {
1906 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1907 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001908 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1909 }
1910
1911 return false;
1912}
1913
buzbee4f4dfc72012-07-02 14:54:44 -07001914char remapShorty(char shortyType) {
1915 /*
1916 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1917 * and longs/doubles are represented as a pair of registers. When sub-word
1918 * arguments (and method results) are passed, they are extended to Dalvik
1919 * virtual register containers. Because llvm is picky about type consistency,
1920 * we must either cast the "real" type to 32-bit container multiple Dalvik
1921 * register types, or always use the expanded values.
1922 * Here, we're doing the latter. We map the shorty signature to container
1923 * types (which is valid so long as we always do a real expansion of passed
1924 * arguments and field loads).
1925 */
1926 switch(shortyType) {
1927 case 'Z' : shortyType = 'I'; break;
1928 case 'B' : shortyType = 'I'; break;
1929 case 'S' : shortyType = 'I'; break;
1930 case 'C' : shortyType = 'I'; break;
1931 default: break;
1932 }
1933 return shortyType;
1934}
1935
buzbee2cfc6392012-05-07 14:51:40 -07001936llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1937
1938 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001939 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001940 greenland::kAccurate);
1941
1942 // Get argument type
1943 std::vector<llvm::Type*> args_type;
1944
1945 // method object
1946 args_type.push_back(cUnit->irb->GetJMethodTy());
1947
1948 // Do we have a "this"?
1949 if ((cUnit->access_flags & kAccStatic) == 0) {
1950 args_type.push_back(cUnit->irb->GetJObjectTy());
1951 }
1952
1953 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001954 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001955 greenland::kAccurate));
1956 }
1957
1958 return llvm::FunctionType::get(ret_type, args_type, false);
1959}
1960
1961bool createFunction(CompilationUnit* cUnit) {
1962 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1963 /* with_signature */ false));
1964 llvm::FunctionType* func_type = getFunctionType(cUnit);
1965
1966 if (func_type == NULL) {
1967 return false;
1968 }
1969
1970 cUnit->func = llvm::Function::Create(func_type,
1971 llvm::Function::ExternalLinkage,
1972 func_name, cUnit->module);
1973
1974 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1975 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1976
1977 arg_iter->setName("method");
1978 ++arg_iter;
1979
1980 int startSReg = cUnit->numRegs;
1981
1982 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1983 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1984 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1985 }
1986
1987 return true;
1988}
1989
1990bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1991{
1992 // Skip the exit block
buzbeed1643e42012-09-05 14:06:51 -07001993 if ((bb->blockType == kDead) ||(bb->blockType == kExitBlock)) {
buzbee2cfc6392012-05-07 14:51:40 -07001994 cUnit->idToBlockMap.Put(bb->id, NULL);
1995 } else {
1996 int offset = bb->startOffset;
1997 bool entryBlock = (bb->blockType == kEntryBlock);
1998 llvm::BasicBlock* llvmBB =
1999 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
buzbee8320f382012-09-11 16:29:42 -07002000 StringPrintf(kLabelFormat, bb->catchEntry ? kCatchBlock :
2001 kNormalBlock, offset, bb->id), cUnit->func);
buzbee2cfc6392012-05-07 14:51:40 -07002002 if (entryBlock) {
2003 cUnit->entryBB = llvmBB;
2004 cUnit->placeholderBB =
2005 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
2006 cUnit->func);
2007 }
2008 cUnit->idToBlockMap.Put(bb->id, llvmBB);
2009 }
2010 return false;
2011}
2012
2013
2014/*
2015 * Convert MIR to LLVM_IR
2016 * o For each ssa name, create LLVM named value. Type these
2017 * appropriately, and ignore high half of wide and double operands.
2018 * o For each MIR basic block, create an LLVM basic block.
2019 * o Iterate through the MIR a basic block at a time, setting arguments
2020 * to recovered ssa name.
2021 */
2022void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
2023{
2024 initIR(cUnit);
2025 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
2026
2027 // Create the function
2028 createFunction(cUnit);
2029
2030 // Create an LLVM basic block for each MIR block in dfs preorder
2031 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
2032 kPreOrderDFSTraversal, false /* isIterative */);
2033 /*
2034 * Create an llvm named value for each MIR SSA name. Note: we'll use
2035 * placeholders for all non-argument values (because we haven't seen
2036 * the definition yet).
2037 */
2038 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2039 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2040 arg_iter++; /* Skip path method */
2041 for (int i = 0; i < cUnit->numSSARegs; i++) {
2042 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07002043 RegLocation rlTemp = cUnit->regLocation[i];
2044 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07002045 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
2046 } else if ((i < cUnit->numRegs) ||
2047 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07002048 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
2049 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07002050 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
2051 val->setName(llvmSSAName(cUnit, i));
buzbee2cfc6392012-05-07 14:51:40 -07002052 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
buzbee2cfc6392012-05-07 14:51:40 -07002053 } else {
2054 // Recover previously-created argument values
2055 llvm::Value* argVal = arg_iter++;
2056 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
2057 }
2058 }
buzbee2cfc6392012-05-07 14:51:40 -07002059
2060 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
2061 kPreOrderDFSTraversal, false /* Iterative */);
2062
buzbee4be777b2012-07-12 14:38:18 -07002063 /*
2064 * In a few rare cases of verification failure, the verifier will
2065 * replace one or more Dalvik opcodes with the special
2066 * throw-verification-failure opcode. This can leave the SSA graph
2067 * in an invalid state, as definitions may be lost, while uses retained.
2068 * To work around this problem, we insert placeholder definitions for
2069 * all Dalvik SSA regs in the "placeholder" block. Here, after
2070 * bitcode conversion is complete, we examine those placeholder definitions
2071 * and delete any with no references (which normally is all of them).
2072 *
2073 * If any definitions remain, we link the placeholder block into the
2074 * CFG. Otherwise, it is deleted.
2075 */
2076 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
2077 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
2078 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2079 DCHECK(inst != NULL);
2080 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2081 DCHECK(val != NULL);
2082 if (val->getNumUses() == 0) {
2083 inst->eraseFromParent();
2084 }
2085 }
2086 setDexOffset(cUnit, 0);
2087 if (cUnit->placeholderBB->empty()) {
2088 cUnit->placeholderBB->eraseFromParent();
2089 } else {
2090 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2091 cUnit->irb->CreateBr(cUnit->entryTargetBB);
2092 cUnit->entryTargetBB = cUnit->placeholderBB;
2093 }
2094 cUnit->irb->SetInsertPoint(cUnit->entryBB);
2095 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07002096
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002097 if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
2098 if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
2099 LOG(INFO) << "Bitcode verification FAILED for "
2100 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
2101 << " of size " << cUnit->insnsSize;
2102 cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
2103 }
2104 }
buzbee2cfc6392012-05-07 14:51:40 -07002105
buzbeead8f15e2012-06-18 14:49:45 -07002106 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
2107 // Write bitcode to file
2108 std::string errmsg;
2109 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
2110 oatReplaceSpecialChars(fname);
2111 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07002112 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002113
buzbeead8f15e2012-06-18 14:49:45 -07002114 llvm::OwningPtr<llvm::tool_output_file> out_file(
2115 new llvm::tool_output_file(fname.c_str(), errmsg,
2116 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002117
buzbeead8f15e2012-06-18 14:49:45 -07002118 if (!errmsg.empty()) {
2119 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2120 }
2121
2122 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2123 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002124 }
buzbee2cfc6392012-05-07 14:51:40 -07002125}
2126
2127RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2128 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002129 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002130 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2131 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002132 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002133 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002134 // FIXME: need to be more robust, handle FP and be in a position to
2135 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002136 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2137 memset(&res, 0, sizeof(res));
2138 res.location = kLocPhysReg;
2139 res.lowReg = oatAllocTemp(cUnit);
2140 res.home = true;
2141 res.sRegLow = INVALID_SREG;
2142 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002143 llvm::Type* ty = val->getType();
2144 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2145 (ty == cUnit->irb->getDoubleTy()));
2146 if (res.wide) {
2147 res.highReg = oatAllocTemp(cUnit);
2148 }
buzbee4f1181f2012-06-22 13:52:12 -07002149 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002150 } else {
2151 DCHECK_EQ(valName[0], 'v');
2152 int baseSReg = INVALID_SREG;
2153 sscanf(valName.c_str(), "v%d_", &baseSReg);
2154 res = cUnit->regLocation[baseSReg];
2155 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002156 }
2157 } else {
2158 res = it->second;
2159 }
2160 return res;
2161}
2162
2163Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2164{
2165 Instruction::Code res = Instruction::NOP;
2166 if (isWide) {
2167 switch(op) {
2168 case kOpAdd: res = Instruction::ADD_LONG; break;
2169 case kOpSub: res = Instruction::SUB_LONG; break;
2170 case kOpMul: res = Instruction::MUL_LONG; break;
2171 case kOpDiv: res = Instruction::DIV_LONG; break;
2172 case kOpRem: res = Instruction::REM_LONG; break;
2173 case kOpAnd: res = Instruction::AND_LONG; break;
2174 case kOpOr: res = Instruction::OR_LONG; break;
2175 case kOpXor: res = Instruction::XOR_LONG; break;
2176 case kOpLsl: res = Instruction::SHL_LONG; break;
2177 case kOpLsr: res = Instruction::USHR_LONG; break;
2178 case kOpAsr: res = Instruction::SHR_LONG; break;
2179 default: LOG(FATAL) << "Unexpected OpKind " << op;
2180 }
2181 } else if (isConst){
2182 switch(op) {
2183 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2184 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2185 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2186 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2187 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2188 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2189 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2190 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2191 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2192 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2193 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2194 default: LOG(FATAL) << "Unexpected OpKind " << op;
2195 }
2196 } else {
2197 switch(op) {
2198 case kOpAdd: res = Instruction::ADD_INT; break;
2199 case kOpSub: res = Instruction::SUB_INT; break;
2200 case kOpMul: res = Instruction::MUL_INT; break;
2201 case kOpDiv: res = Instruction::DIV_INT; break;
2202 case kOpRem: res = Instruction::REM_INT; break;
2203 case kOpAnd: res = Instruction::AND_INT; break;
2204 case kOpOr: res = Instruction::OR_INT; break;
2205 case kOpXor: res = Instruction::XOR_INT; break;
2206 case kOpLsl: res = Instruction::SHL_INT; break;
2207 case kOpLsr: res = Instruction::USHR_INT; break;
2208 case kOpAsr: res = Instruction::SHR_INT; break;
2209 default: LOG(FATAL) << "Unexpected OpKind " << op;
2210 }
2211 }
2212 return res;
2213}
2214
buzbee4f1181f2012-06-22 13:52:12 -07002215Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2216{
2217 Instruction::Code res = Instruction::NOP;
2218 if (isWide) {
2219 switch(op) {
2220 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2221 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2222 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2223 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2224 case kOpRem: res = Instruction::REM_DOUBLE; break;
2225 default: LOG(FATAL) << "Unexpected OpKind " << op;
2226 }
2227 } else {
2228 switch(op) {
2229 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2230 case kOpSub: res = Instruction::SUB_FLOAT; break;
2231 case kOpMul: res = Instruction::MUL_FLOAT; break;
2232 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2233 case kOpRem: res = Instruction::REM_FLOAT; break;
2234 default: LOG(FATAL) << "Unexpected OpKind " << op;
2235 }
2236 }
2237 return res;
2238}
2239
2240void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2241{
2242 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002243 /*
2244 * Normally, we won't ever generate an FP operation with an immediate
2245 * operand (not supported in Dex instruction set). However, the IR builder
2246 * may insert them - in particular for createNegFP. Recognize this case
2247 * and deal with it.
2248 */
2249 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2250 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2251 DCHECK(op2C == NULL);
2252 if ((op1C != NULL) && (op == kOpSub)) {
2253 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2254 if (rlDest.wide) {
2255 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2256 } else {
2257 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2258 }
buzbee4f1181f2012-06-22 13:52:12 -07002259 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002260 DCHECK(op1C == NULL);
2261 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2262 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2263 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2264 if (rlDest.wide) {
2265 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2266 } else {
2267 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2268 }
buzbee4f1181f2012-06-22 13:52:12 -07002269 }
2270}
2271
buzbee101305f2012-06-28 18:00:56 -07002272void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2273 Instruction::Code opcode)
2274{
2275 RegLocation rlDest = getLoc(cUnit, inst);
2276 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2277 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2278}
2279
buzbee76592632012-06-29 15:18:35 -07002280void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2281{
2282 RegLocation rlDest = getLoc(cUnit, inst);
2283 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2284 Instruction::Code opcode;
2285 if (rlDest.wide) {
2286 if (rlSrc.wide) {
2287 opcode = Instruction::LONG_TO_DOUBLE;
2288 } else {
2289 opcode = Instruction::INT_TO_DOUBLE;
2290 }
2291 } else {
2292 if (rlSrc.wide) {
2293 opcode = Instruction::LONG_TO_FLOAT;
2294 } else {
2295 opcode = Instruction::INT_TO_FLOAT;
2296 }
2297 }
2298 genConversion(cUnit, opcode, rlDest, rlSrc);
2299}
2300
TDYa1274ec8ccd2012-08-11 07:04:57 -07002301void cvtFPToInt(CompilationUnit* cUnit, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002302{
TDYa1274ec8ccd2012-08-11 07:04:57 -07002303 RegLocation rlDest = getLoc(cUnit, call_inst);
2304 RegLocation rlSrc = getLoc(cUnit, call_inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002305 Instruction::Code opcode;
2306 if (rlDest.wide) {
2307 if (rlSrc.wide) {
2308 opcode = Instruction::DOUBLE_TO_LONG;
2309 } else {
2310 opcode = Instruction::FLOAT_TO_LONG;
2311 }
2312 } else {
2313 if (rlSrc.wide) {
2314 opcode = Instruction::DOUBLE_TO_INT;
2315 } else {
2316 opcode = Instruction::FLOAT_TO_INT;
2317 }
2318 }
2319 genConversion(cUnit, opcode, rlDest, rlSrc);
2320}
2321
2322void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2323{
2324 RegLocation rlDest = getLoc(cUnit, inst);
2325 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2326 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2327}
2328
2329void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2330{
2331 RegLocation rlDest = getLoc(cUnit, inst);
2332 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2333 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2334 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2335 storeValue(cUnit, rlDest, rlSrc);
2336}
2337
2338void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2339{
2340 RegLocation rlDest = getLoc(cUnit, inst);
2341 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2342 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2343}
2344
2345
buzbee101305f2012-06-28 18:00:56 -07002346void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2347{
2348 // TODO: evaluate src/tgt types and add general support for more than int to long
2349 RegLocation rlDest = getLoc(cUnit, inst);
2350 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2351 DCHECK(rlDest.wide);
2352 DCHECK(!rlSrc.wide);
2353 DCHECK(!rlDest.fp);
2354 DCHECK(!rlSrc.fp);
2355 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2356 if (rlSrc.location == kLocPhysReg) {
2357 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2358 } else {
2359 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2360 }
2361 if (isSigned) {
2362 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2363 } else {
2364 loadConstant(cUnit, rlResult.highReg, 0);
2365 }
2366 storeValueWide(cUnit, rlDest, rlResult);
2367}
2368
buzbee2cfc6392012-05-07 14:51:40 -07002369void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2370{
2371 RegLocation rlDest = getLoc(cUnit, inst);
2372 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002373 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002374 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2375 if ((op == kOpSub) && (lhsImm != NULL)) {
2376 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002377 if (rlSrc1.wide) {
2378 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2379 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2380 } else {
2381 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2382 lhsImm->getSExtValue());
2383 }
buzbee4f1181f2012-06-22 13:52:12 -07002384 return;
2385 }
2386 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002387 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2388 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002389 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2390 if (!rlDest.wide && (constRhs != NULL)) {
buzbee2cfc6392012-05-07 14:51:40 -07002391 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
buzbee9a2487f2012-07-26 14:01:13 -07002392 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002393 } else {
2394 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002395 RegLocation rlSrc2;
2396 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002397 // ir_builder converts NOT_LONG to xor src, -1. Restore
2398 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2399 DCHECK_EQ(-1L, constRhs->getSExtValue());
2400 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002401 rlSrc2 = rlSrc1;
2402 } else {
2403 rlSrc2 = getLoc(cUnit, rhs);
2404 }
buzbee2cfc6392012-05-07 14:51:40 -07002405 if (rlDest.wide) {
2406 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2407 } else {
2408 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2409 }
2410 }
2411}
2412
buzbee2a83e8f2012-07-13 16:42:30 -07002413void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2414 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002415{
buzbee2a83e8f2012-07-13 16:42:30 -07002416 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2417 RegLocation rlDest = getLoc(cUnit, callInst);
2418 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2419 llvm::Value* rhs = callInst->getArgOperand(1);
2420 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2421 DCHECK(!rlDest.wide);
2422 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002423 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002424 RegLocation rlShift = getLoc(cUnit, rhs);
2425 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2426 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2427 } else {
2428 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2429 }
buzbee101305f2012-06-28 18:00:56 -07002430 }
2431}
2432
buzbee2cfc6392012-05-07 14:51:40 -07002433void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2434{
2435 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2436 DCHECK(brInst != NULL);
2437 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2438 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2439 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2440}
2441
2442void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2443{
2444 // Nop - these have already been processed
2445}
2446
2447void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2448{
2449 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2450 llvm::Value* retVal = retInst->getReturnValue();
2451 if (retVal != NULL) {
2452 RegLocation rlSrc = getLoc(cUnit, retVal);
2453 if (rlSrc.wide) {
2454 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2455 } else {
2456 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2457 }
2458 }
2459 genExitSequence(cUnit);
2460}
2461
2462ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2463{
2464 ConditionCode res = kCondAl;
2465 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002466 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002467 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2468 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2469 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002470 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002471 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002472 default: LOG(FATAL) << "Unexpected llvm condition";
2473 }
2474 return res;
2475}
2476
2477void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2478{
2479 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2480 UNIMPLEMENTED(FATAL);
2481}
2482
2483void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2484 llvm::BranchInst* brInst)
2485{
2486 // Get targets
2487 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2488 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2489 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2490 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2491 // Get comparison operands
2492 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2493 ConditionCode cond = getCond(iCmpInst->getPredicate());
2494 llvm::Value* lhs = iCmpInst->getOperand(0);
2495 // Not expecting a constant as 1st operand
2496 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2497 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2498 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2499 llvm::Value* rhs = inst->getOperand(1);
2500#if defined(TARGET_MIPS)
2501 // Compare and branch in one shot
2502 (void)taken;
2503 (void)cond;
2504 (void)rhs;
2505 UNIMPLEMENTED(FATAL);
2506#else
2507 //Compare, then branch
2508 // TODO: handle fused CMP_LONG/IF_xxZ case
2509 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2510 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002511 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2512 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002513 } else {
2514 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2515 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2516 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2517 }
2518 opCondBranch(cUnit, cond, taken);
2519#endif
2520 // Fallthrough
2521 opUnconditionalBranch(cUnit, fallThrough);
2522}
2523
2524void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2525 llvm::Function* callee)
2526{
2527 UNIMPLEMENTED(FATAL);
2528}
2529
buzbee2cfc6392012-05-07 14:51:40 -07002530void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2531{
buzbee4f1181f2012-06-22 13:52:12 -07002532 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002533 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2534 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002535 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2536 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002537 if (rlSrc.wide) {
2538 storeValueWide(cUnit, rlDest, rlSrc);
2539 } else {
2540 storeValue(cUnit, rlDest, rlSrc);
2541 }
2542}
2543
2544// Note: Immediate arg is a ConstantInt regardless of result type
2545void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2546{
buzbee4f1181f2012-06-22 13:52:12 -07002547 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002548 llvm::ConstantInt* src =
2549 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2550 uint64_t immval = src->getZExtValue();
2551 RegLocation rlDest = getLoc(cUnit, callInst);
2552 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2553 if (rlDest.wide) {
2554 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2555 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2556 storeValueWide(cUnit, rlDest, rlResult);
2557 } else {
2558 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2559 storeValue(cUnit, rlDest, rlResult);
2560 }
2561}
2562
buzbee101305f2012-06-28 18:00:56 -07002563void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2564 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002565{
buzbee4f1181f2012-06-22 13:52:12 -07002566 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002567 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002568 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002569 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002570 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002571 if (isString) {
2572 genConstString(cUnit, index, rlDest);
2573 } else {
2574 genConstClass(cUnit, index, rlDest);
2575 }
2576}
2577
2578void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2579{
2580 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2581 llvm::ConstantInt* offsetVal =
2582 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2583 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2584 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002585}
2586
buzbee4f1181f2012-06-22 13:52:12 -07002587void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2588{
buzbee32412962012-06-26 16:27:56 -07002589 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002590 llvm::ConstantInt* typeIdxVal =
2591 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2592 uint32_t typeIdx = typeIdxVal->getZExtValue();
2593 RegLocation rlDest = getLoc(cUnit, callInst);
2594 genNewInstance(cUnit, typeIdx, rlDest);
2595}
2596
buzbee8fa0fda2012-06-27 15:44:52 -07002597void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2598{
2599 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2600 llvm::ConstantInt* typeIdxVal =
2601 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2602 uint32_t typeIdx = typeIdxVal->getZExtValue();
2603 llvm::Value* len = callInst->getArgOperand(1);
2604 RegLocation rlLen = getLoc(cUnit, len);
2605 RegLocation rlDest = getLoc(cUnit, callInst);
2606 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2607}
2608
2609void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2610{
2611 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2612 llvm::ConstantInt* typeIdxVal =
2613 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2614 uint32_t typeIdx = typeIdxVal->getZExtValue();
2615 llvm::Value* src = callInst->getArgOperand(1);
2616 RegLocation rlSrc = getLoc(cUnit, src);
2617 RegLocation rlDest = getLoc(cUnit, callInst);
2618 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2619}
2620
buzbee32412962012-06-26 16:27:56 -07002621void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2622{
2623 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2624 llvm::Value* src = callInst->getArgOperand(0);
2625 RegLocation rlSrc = getLoc(cUnit, src);
2626 genThrow(cUnit, rlSrc);
2627}
2628
buzbee8fa0fda2012-06-27 15:44:52 -07002629void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2630 llvm::CallInst* callInst)
2631{
2632 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2633 llvm::ConstantInt* optFlags =
2634 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2635 llvm::Value* src = callInst->getArgOperand(1);
2636 RegLocation rlSrc = getLoc(cUnit, src);
2637 if (isEnter) {
2638 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2639 } else {
2640 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2641 }
2642}
2643
buzbee76592632012-06-29 15:18:35 -07002644void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002645{
2646 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2647 llvm::ConstantInt* optFlags =
2648 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2649 llvm::Value* src = callInst->getArgOperand(1);
2650 RegLocation rlSrc = getLoc(cUnit, src);
2651 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2652 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2653 RegLocation rlDest = getLoc(cUnit, callInst);
2654 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2655 int lenOffset = Array::LengthOffset().Int32Value();
2656 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2657 storeValue(cUnit, rlDest, rlResult);
2658}
2659
buzbee32412962012-06-26 16:27:56 -07002660void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2661{
2662 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
2663 int exOffset = Thread::ExceptionOffset().Int32Value();
2664 RegLocation rlDest = getLoc(cUnit, callInst);
2665 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2666#if defined(TARGET_X86)
2667 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
2668 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
2669#else
2670 int resetReg = oatAllocTemp(cUnit);
2671 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
2672 loadConstant(cUnit, resetReg, 0);
2673 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
2674 oatFreeTemp(cUnit, resetReg);
2675#endif
2676 storeValue(cUnit, rlDest, rlResult);
2677}
2678
buzbee4f1181f2012-06-22 13:52:12 -07002679void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2680 bool isObject)
2681{
buzbee32412962012-06-26 16:27:56 -07002682 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002683 llvm::ConstantInt* typeIdxVal =
2684 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2685 uint32_t typeIdx = typeIdxVal->getZExtValue();
2686 RegLocation rlDest = getLoc(cUnit, callInst);
2687 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2688}
2689
buzbee8fa0fda2012-06-27 15:44:52 -07002690void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2691 bool isObject)
2692{
2693 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2694 llvm::ConstantInt* typeIdxVal =
2695 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2696 uint32_t typeIdx = typeIdxVal->getZExtValue();
2697 llvm::Value* src = callInst->getArgOperand(1);
2698 RegLocation rlSrc = getLoc(cUnit, src);
2699 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2700}
2701
2702void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2703 int scale)
2704{
2705 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2706 llvm::ConstantInt* optFlags =
2707 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2708 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2709 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2710 RegLocation rlDest = getLoc(cUnit, callInst);
2711 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2712 rlDest, scale);
2713}
2714
2715void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002716 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002717{
2718 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2719 llvm::ConstantInt* optFlags =
2720 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2721 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2722 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2723 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002724 if (isObject) {
2725 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2726 rlSrc, scale);
2727 } else {
2728 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2729 rlSrc, scale);
2730 }
2731}
2732
2733void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2734{
2735 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2736}
2737
2738void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2739 OpSize size, int scale)
2740{
2741 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002742}
2743
buzbee101305f2012-06-28 18:00:56 -07002744void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2745 bool isWide, bool isObj)
2746{
2747 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2748 llvm::ConstantInt* optFlags =
2749 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2750 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2751 llvm::ConstantInt* fieldIdx =
2752 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2753 RegLocation rlDest = getLoc(cUnit, callInst);
2754 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2755 size, rlDest, rlObj, isWide, isObj);
2756}
2757
2758void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2759 bool isWide, bool isObj)
2760{
2761 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2762 llvm::ConstantInt* optFlags =
2763 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2764 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2765 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2766 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002767 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002768 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2769 size, rlSrc, rlObj, isWide, isObj);
2770}
2771
2772void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2773{
2774 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2775 llvm::ConstantInt* typeIdx =
2776 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2777 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2778 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2779}
2780
buzbee76592632012-06-29 15:18:35 -07002781void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2782 Instruction::Code opcode)
2783{
2784 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2785 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2786 RegLocation rlDest = getLoc(cUnit, callInst);
2787 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2788}
2789
2790void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2791{
2792 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2793 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2794 RegLocation rlDest = getLoc(cUnit, callInst);
2795 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2796}
2797
buzbeef58c12c2012-07-03 15:06:29 -07002798void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2799{
2800 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2801 DCHECK(swInst != NULL);
2802 llvm::Value* testVal = swInst->getCondition();
2803 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2804 DCHECK(tableOffsetNode != NULL);
2805 llvm::ConstantInt* tableOffsetValue =
2806 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2807 int32_t tableOffset = tableOffsetValue->getSExtValue();
2808 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeea1da8a52012-07-09 14:00:21 -07002809 const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2810 u2 tableMagic = *table;
2811 if (tableMagic == 0x100) {
2812 genPackedSwitch(cUnit, tableOffset, rlSrc);
2813 } else {
2814 DCHECK_EQ(tableMagic, 0x200);
2815 genSparseSwitch(cUnit, tableOffset, rlSrc);
2816 }
buzbeef58c12c2012-07-03 15:06:29 -07002817}
2818
buzbee6969d502012-06-15 16:40:31 -07002819void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002820 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002821{
2822 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2823 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002824 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002825 info->result.location = kLocInvalid;
2826 } else {
2827 info->result = getLoc(cUnit, callInst);
2828 }
2829 llvm::ConstantInt* invokeTypeVal =
2830 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2831 llvm::ConstantInt* methodIndexVal =
2832 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2833 llvm::ConstantInt* optFlagsVal =
2834 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2835 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2836 info->index = methodIndexVal->getZExtValue();
2837 info->optFlags = optFlagsVal->getZExtValue();
2838 info->offset = cUnit->currentDalvikOffset;
2839
buzbee6969d502012-06-15 16:40:31 -07002840 // Count the argument words, and then build argument array.
2841 info->numArgWords = 0;
2842 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2843 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2844 info->numArgWords += tLoc.wide ? 2 : 1;
2845 }
2846 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2847 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2848 // Now, fill in the location records, synthesizing high loc of wide vals
2849 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002850 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002851 if (info->args[next].wide) {
2852 next++;
2853 // TODO: Might make sense to mark this as an invalid loc
2854 info->args[next].origSReg = info->args[next-1].origSReg+1;
2855 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2856 }
2857 next++;
2858 }
buzbee4f4dfc72012-07-02 14:54:44 -07002859 // TODO - rework such that we no longer need isRange
2860 info->isRange = (info->numArgWords > 5);
2861
buzbee76592632012-06-29 15:18:35 -07002862 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002863 genFilledNewArray(cUnit, info);
2864 } else {
2865 genInvoke(cUnit, info);
2866 }
buzbee6969d502012-06-15 16:40:31 -07002867}
2868
buzbeead8f15e2012-06-18 14:49:45 -07002869/* Look up the RegLocation associated with a Value. Must already be defined */
2870RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2871{
2872 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2873 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2874 return it->second;
2875}
2876
buzbee2cfc6392012-05-07 14:51:40 -07002877bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2878{
buzbee0967a252012-09-14 10:43:54 -07002879 while (cUnit->llvmBlocks.find(bb) == cUnit->llvmBlocks.end()) {
2880 llvm::BasicBlock* nextBB = NULL;
2881 cUnit->llvmBlocks.insert(bb);
2882 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2883 // Define the starting label
2884 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2885 // Extract the type and starting offset from the block's name
2886 char blockType = kNormalBlock;
2887 if (!isEntry) {
2888 const char* blockName = bb->getName().str().c_str();
2889 int dummy;
2890 sscanf(blockName, kLabelFormat, &blockType, &blockLabel->operands[0], &dummy);
2891 cUnit->currentDalvikOffset = blockLabel->operands[0];
2892 } else {
2893 cUnit->currentDalvikOffset = 0;
2894 }
2895 // Set the label kind
2896 blockLabel->opcode = kPseudoNormalBlockLabel;
2897 // Insert the label
2898 oatAppendLIR(cUnit, blockLabel);
buzbee2cfc6392012-05-07 14:51:40 -07002899
buzbee0967a252012-09-14 10:43:54 -07002900 LIR* headLIR = NULL;
buzbee8320f382012-09-11 16:29:42 -07002901
buzbee0967a252012-09-14 10:43:54 -07002902 if (blockType == kCatchBlock) {
2903 headLIR = newLIR0(cUnit, kPseudoSafepointPC);
2904 }
buzbee8320f382012-09-11 16:29:42 -07002905
buzbee0967a252012-09-14 10:43:54 -07002906 // Free temp registers and reset redundant store tracking */
2907 oatResetRegPool(cUnit);
2908 oatResetDefTracking(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002909
buzbee0967a252012-09-14 10:43:54 -07002910 //TODO: restore oat incoming liveness optimization
2911 oatClobberAllRegs(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002912
buzbee0967a252012-09-14 10:43:54 -07002913 if (isEntry) {
2914 RegLocation* argLocs = (RegLocation*)
2915 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2916 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2917 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2918 // Skip past Method*
2919 it++;
2920 for (unsigned i = 0; it != it_end; ++it) {
2921 llvm::Value* val = it;
2922 argLocs[i++] = valToLoc(cUnit, val);
2923 llvm::Type* ty = val->getType();
2924 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2925 argLocs[i] = argLocs[i-1];
2926 argLocs[i].lowReg = argLocs[i].highReg;
2927 argLocs[i].origSReg++;
2928 argLocs[i].sRegLow = INVALID_SREG;
2929 argLocs[i].highWord = true;
2930 i++;
2931 }
2932 }
2933 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
2934 }
2935
2936 // Visit all of the instructions in the block
2937 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2938 llvm::Instruction* inst = it;
2939 llvm::BasicBlock::iterator nextIt = ++it;
2940 // Extract the Dalvik offset from the instruction
2941 uint32_t opcode = inst->getOpcode();
2942 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2943 if (dexOffsetNode != NULL) {
2944 llvm::ConstantInt* dexOffsetValue =
2945 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2946 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2947 }
2948
2949 oatResetRegPool(cUnit);
2950 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2951 oatClobberAllRegs(cUnit);
2952 }
2953
2954 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2955 oatResetDefTracking(cUnit);
2956 }
2957
2958 #ifndef NDEBUG
2959 /* Reset temp tracking sanity check */
2960 cUnit->liveSReg = INVALID_SREG;
2961 #endif
2962
2963 // TODO: use llvm opcode name here instead of "boundary" if verbose
2964 LIR* boundaryLIR = markBoundary(cUnit, cUnit->currentDalvikOffset, "boundary");
2965
2966 /* Remember the first LIR for thisl block*/
2967 if (headLIR == NULL) {
2968 headLIR = boundaryLIR;
2969 headLIR->defMask = ENCODE_ALL;
2970 }
2971
2972 switch(opcode) {
2973
2974 case llvm::Instruction::ICmp: {
2975 llvm::Instruction* nextInst = nextIt;
2976 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2977 if (brInst != NULL /* and... */) {
2978 cvtICmpBr(cUnit, inst, brInst);
2979 ++it;
2980 } else {
2981 cvtICmp(cUnit, inst);
2982 }
2983 }
2984 break;
2985
2986 case llvm::Instruction::Call: {
2987 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2988 llvm::Function* callee = callInst->getCalledFunction();
2989 greenland::IntrinsicHelper::IntrinsicId id =
2990 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2991 switch (id) {
2992 case greenland::IntrinsicHelper::AllocaShadowFrame:
2993 case greenland::IntrinsicHelper::SetShadowFrameEntry:
2994 case greenland::IntrinsicHelper::PopShadowFrame:
2995 // Ignore shadow frame stuff for quick compiler
2996 break;
2997 case greenland::IntrinsicHelper::CopyInt:
2998 case greenland::IntrinsicHelper::CopyObj:
2999 case greenland::IntrinsicHelper::CopyFloat:
3000 case greenland::IntrinsicHelper::CopyLong:
3001 case greenland::IntrinsicHelper::CopyDouble:
3002 cvtCopy(cUnit, callInst);
3003 break;
3004 case greenland::IntrinsicHelper::ConstInt:
3005 case greenland::IntrinsicHelper::ConstObj:
3006 case greenland::IntrinsicHelper::ConstLong:
3007 case greenland::IntrinsicHelper::ConstFloat:
3008 case greenland::IntrinsicHelper::ConstDouble:
3009 cvtConst(cUnit, callInst);
3010 break;
3011 case greenland::IntrinsicHelper::DivInt:
3012 case greenland::IntrinsicHelper::DivLong:
3013 cvtBinOp(cUnit, kOpDiv, inst);
3014 break;
3015 case greenland::IntrinsicHelper::RemInt:
3016 case greenland::IntrinsicHelper::RemLong:
3017 cvtBinOp(cUnit, kOpRem, inst);
3018 break;
3019 case greenland::IntrinsicHelper::MethodInfo:
3020 // Already dealt with - just ignore it here.
3021 break;
3022 case greenland::IntrinsicHelper::CheckSuspend:
3023 genSuspendTest(cUnit, 0 /* optFlags already applied */);
3024 break;
3025 case greenland::IntrinsicHelper::HLInvokeObj:
3026 case greenland::IntrinsicHelper::HLInvokeFloat:
3027 case greenland::IntrinsicHelper::HLInvokeDouble:
3028 case greenland::IntrinsicHelper::HLInvokeLong:
3029 case greenland::IntrinsicHelper::HLInvokeInt:
3030 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
3031 break;
3032 case greenland::IntrinsicHelper::HLInvokeVoid:
3033 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
3034 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003035 case greenland::IntrinsicHelper::HLFilledNewArray:
buzbee0967a252012-09-14 10:43:54 -07003036 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
3037 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003038 case greenland::IntrinsicHelper::HLFillArrayData:
buzbee0967a252012-09-14 10:43:54 -07003039 cvtFillArrayData(cUnit, callInst);
3040 break;
3041 case greenland::IntrinsicHelper::ConstString:
3042 cvtConstObject(cUnit, callInst, true /* isString */);
3043 break;
3044 case greenland::IntrinsicHelper::ConstClass:
3045 cvtConstObject(cUnit, callInst, false /* isString */);
3046 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003047 case greenland::IntrinsicHelper::HLCheckCast:
buzbee0967a252012-09-14 10:43:54 -07003048 cvtCheckCast(cUnit, callInst);
3049 break;
3050 case greenland::IntrinsicHelper::NewInstance:
3051 cvtNewInstance(cUnit, callInst);
3052 break;
3053 case greenland::IntrinsicHelper::HLSgetObject:
3054 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
3055 break;
3056 case greenland::IntrinsicHelper::HLSget:
3057 case greenland::IntrinsicHelper::HLSgetFloat:
3058 case greenland::IntrinsicHelper::HLSgetBoolean:
3059 case greenland::IntrinsicHelper::HLSgetByte:
3060 case greenland::IntrinsicHelper::HLSgetChar:
3061 case greenland::IntrinsicHelper::HLSgetShort:
3062 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
3063 break;
3064 case greenland::IntrinsicHelper::HLSgetWide:
3065 case greenland::IntrinsicHelper::HLSgetDouble:
3066 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
3067 break;
3068 case greenland::IntrinsicHelper::HLSput:
3069 case greenland::IntrinsicHelper::HLSputFloat:
3070 case greenland::IntrinsicHelper::HLSputBoolean:
3071 case greenland::IntrinsicHelper::HLSputByte:
3072 case greenland::IntrinsicHelper::HLSputChar:
3073 case greenland::IntrinsicHelper::HLSputShort:
3074 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
3075 break;
3076 case greenland::IntrinsicHelper::HLSputWide:
3077 case greenland::IntrinsicHelper::HLSputDouble:
3078 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
3079 break;
3080 case greenland::IntrinsicHelper::HLSputObject:
3081 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
3082 break;
3083 case greenland::IntrinsicHelper::GetException:
3084 cvtMoveException(cUnit, callInst);
3085 break;
TDYa127f71bf5a2012-07-29 20:09:52 -07003086 case greenland::IntrinsicHelper::HLThrowException:
buzbee0967a252012-09-14 10:43:54 -07003087 cvtThrow(cUnit, callInst);
3088 break;
3089 case greenland::IntrinsicHelper::MonitorEnter:
3090 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
3091 break;
3092 case greenland::IntrinsicHelper::MonitorExit:
3093 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
3094 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003095 case greenland::IntrinsicHelper::OptArrayLength:
buzbee0967a252012-09-14 10:43:54 -07003096 cvtArrayLength(cUnit, callInst);
3097 break;
3098 case greenland::IntrinsicHelper::NewArray:
3099 cvtNewArray(cUnit, callInst);
3100 break;
3101 case greenland::IntrinsicHelper::InstanceOf:
3102 cvtInstanceOf(cUnit, callInst);
3103 break;
3104
3105 case greenland::IntrinsicHelper::HLArrayGet:
3106 case greenland::IntrinsicHelper::HLArrayGetObject:
3107 case greenland::IntrinsicHelper::HLArrayGetFloat:
3108 cvtAget(cUnit, callInst, kWord, 2);
3109 break;
3110 case greenland::IntrinsicHelper::HLArrayGetWide:
3111 case greenland::IntrinsicHelper::HLArrayGetDouble:
3112 cvtAget(cUnit, callInst, kLong, 3);
3113 break;
3114 case greenland::IntrinsicHelper::HLArrayGetBoolean:
3115 cvtAget(cUnit, callInst, kUnsignedByte, 0);
3116 break;
3117 case greenland::IntrinsicHelper::HLArrayGetByte:
3118 cvtAget(cUnit, callInst, kSignedByte, 0);
3119 break;
3120 case greenland::IntrinsicHelper::HLArrayGetChar:
3121 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
3122 break;
3123 case greenland::IntrinsicHelper::HLArrayGetShort:
3124 cvtAget(cUnit, callInst, kSignedHalf, 1);
3125 break;
3126
3127 case greenland::IntrinsicHelper::HLArrayPut:
3128 case greenland::IntrinsicHelper::HLArrayPutFloat:
3129 cvtAputPrimitive(cUnit, callInst, kWord, 2);
3130 break;
3131 case greenland::IntrinsicHelper::HLArrayPutObject:
3132 cvtAputObj(cUnit, callInst);
3133 break;
3134 case greenland::IntrinsicHelper::HLArrayPutWide:
3135 case greenland::IntrinsicHelper::HLArrayPutDouble:
3136 cvtAputPrimitive(cUnit, callInst, kLong, 3);
3137 break;
3138 case greenland::IntrinsicHelper::HLArrayPutBoolean:
3139 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
3140 break;
3141 case greenland::IntrinsicHelper::HLArrayPutByte:
3142 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
3143 break;
3144 case greenland::IntrinsicHelper::HLArrayPutChar:
3145 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
3146 break;
3147 case greenland::IntrinsicHelper::HLArrayPutShort:
3148 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
3149 break;
3150
3151 case greenland::IntrinsicHelper::HLIGet:
3152 case greenland::IntrinsicHelper::HLIGetFloat:
3153 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3154 break;
3155 case greenland::IntrinsicHelper::HLIGetObject:
3156 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3157 break;
3158 case greenland::IntrinsicHelper::HLIGetWide:
3159 case greenland::IntrinsicHelper::HLIGetDouble:
3160 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3161 break;
3162 case greenland::IntrinsicHelper::HLIGetBoolean:
3163 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3164 false /* obj */);
3165 break;
3166 case greenland::IntrinsicHelper::HLIGetByte:
3167 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3168 false /* obj */);
3169 break;
3170 case greenland::IntrinsicHelper::HLIGetChar:
3171 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3172 false /* obj */);
3173 break;
3174 case greenland::IntrinsicHelper::HLIGetShort:
3175 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3176 false /* obj */);
3177 break;
3178
3179 case greenland::IntrinsicHelper::HLIPut:
3180 case greenland::IntrinsicHelper::HLIPutFloat:
3181 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3182 break;
3183 case greenland::IntrinsicHelper::HLIPutObject:
3184 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3185 break;
3186 case greenland::IntrinsicHelper::HLIPutWide:
3187 case greenland::IntrinsicHelper::HLIPutDouble:
3188 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3189 break;
3190 case greenland::IntrinsicHelper::HLIPutBoolean:
3191 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3192 false /* obj */);
3193 break;
3194 case greenland::IntrinsicHelper::HLIPutByte:
3195 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3196 false /* obj */);
3197 break;
3198 case greenland::IntrinsicHelper::HLIPutChar:
3199 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3200 false /* obj */);
3201 break;
3202 case greenland::IntrinsicHelper::HLIPutShort:
3203 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3204 false /* obj */);
3205 break;
3206
3207 case greenland::IntrinsicHelper::IntToChar:
3208 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3209 break;
3210 case greenland::IntrinsicHelper::IntToShort:
3211 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3212 break;
3213 case greenland::IntrinsicHelper::IntToByte:
3214 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3215 break;
3216
TDYa1274ec8ccd2012-08-11 07:04:57 -07003217 case greenland::IntrinsicHelper::F2I:
3218 case greenland::IntrinsicHelper::D2I:
3219 case greenland::IntrinsicHelper::F2L:
3220 case greenland::IntrinsicHelper::D2L:
3221 cvtFPToInt(cUnit, callInst);
3222 break;
3223
buzbee0967a252012-09-14 10:43:54 -07003224 case greenland::IntrinsicHelper::CmplFloat:
3225 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3226 break;
3227 case greenland::IntrinsicHelper::CmpgFloat:
3228 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3229 break;
3230 case greenland::IntrinsicHelper::CmplDouble:
3231 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3232 break;
3233 case greenland::IntrinsicHelper::CmpgDouble:
3234 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3235 break;
3236
3237 case greenland::IntrinsicHelper::CmpLong:
3238 cvtLongCompare(cUnit, callInst);
3239 break;
3240
3241 case greenland::IntrinsicHelper::SHLLong:
3242 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
3243 break;
3244 case greenland::IntrinsicHelper::SHRLong:
3245 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3246 break;
3247 case greenland::IntrinsicHelper::USHRLong:
3248 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3249 break;
3250 case greenland::IntrinsicHelper::SHLInt:
3251 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3252 break;
3253 case greenland::IntrinsicHelper::SHRInt:
3254 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3255 break;
3256 case greenland::IntrinsicHelper::USHRInt:
3257 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3258 break;
3259
3260 case greenland::IntrinsicHelper::CatchTargets: {
3261 llvm::SwitchInst* swInst =
3262 llvm::dyn_cast<llvm::SwitchInst>(nextIt);
3263 DCHECK(swInst != NULL);
3264 /*
3265 * Discard the edges and the following conditional branch.
3266 * Do a direct branch to the default target (which is the
3267 * "work" portion of the pair.
3268 * TODO: awful code layout - rework
3269 */
3270 llvm::BasicBlock* targetBB = swInst->getDefaultDest();
3271 DCHECK(targetBB != NULL);
3272 opUnconditionalBranch(cUnit,
3273 cUnit->blockToLabelMap.Get(targetBB));
3274 ++it;
3275 // Set next bb to default target - improves code layout
3276 nextBB = targetBB;
3277 }
3278 break;
3279
3280 default:
3281 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3282 << cUnit->intrinsic_helper->GetName(id);
3283 }
3284 }
3285 break;
3286
3287 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3288 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3289 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3290 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3291 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3292 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3293 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3294 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3295 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
3296 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3297 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
3298 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3299 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3300 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3301 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3302 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
3303 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003304 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3305 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3306 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
3307
3308 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3309 break;
3310 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3311 break;
3312
3313 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3314
3315 case llvm::Instruction::Unreachable:
3316 break; // FIXME: can we really ignore these?
3317
3318 case llvm::Instruction::Shl:
3319 case llvm::Instruction::LShr:
3320 case llvm::Instruction::AShr:
3321 case llvm::Instruction::Invoke:
3322 case llvm::Instruction::FPToUI:
TDYa1274ec8ccd2012-08-11 07:04:57 -07003323 case llvm::Instruction::FPToSI:
buzbee0967a252012-09-14 10:43:54 -07003324 case llvm::Instruction::UIToFP:
3325 case llvm::Instruction::PtrToInt:
3326 case llvm::Instruction::IntToPtr:
3327 case llvm::Instruction::FCmp:
3328 case llvm::Instruction::URem:
3329 case llvm::Instruction::UDiv:
3330 case llvm::Instruction::Resume:
3331 case llvm::Instruction::Alloca:
3332 case llvm::Instruction::GetElementPtr:
3333 case llvm::Instruction::Fence:
3334 case llvm::Instruction::AtomicCmpXchg:
3335 case llvm::Instruction::AtomicRMW:
3336 case llvm::Instruction::BitCast:
3337 case llvm::Instruction::VAArg:
3338 case llvm::Instruction::Select:
3339 case llvm::Instruction::UserOp1:
3340 case llvm::Instruction::UserOp2:
3341 case llvm::Instruction::ExtractElement:
3342 case llvm::Instruction::InsertElement:
3343 case llvm::Instruction::ShuffleVector:
3344 case llvm::Instruction::ExtractValue:
3345 case llvm::Instruction::InsertValue:
3346 case llvm::Instruction::LandingPad:
3347 case llvm::Instruction::IndirectBr:
3348 case llvm::Instruction::Load:
3349 case llvm::Instruction::Store:
3350 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3351
3352 default:
3353 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3354 break;
buzbeead8f15e2012-06-18 14:49:45 -07003355 }
3356 }
buzbee2cfc6392012-05-07 14:51:40 -07003357
buzbee0967a252012-09-14 10:43:54 -07003358 if (headLIR != NULL) {
3359 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
buzbee2cfc6392012-05-07 14:51:40 -07003360 }
buzbee0967a252012-09-14 10:43:54 -07003361 if (nextBB != NULL) {
3362 bb = nextBB;
3363 nextBB = NULL;
buzbee6969d502012-06-15 16:40:31 -07003364 }
buzbee6969d502012-06-15 16:40:31 -07003365 }
buzbee2cfc6392012-05-07 14:51:40 -07003366 return false;
3367}
3368
3369/*
3370 * Convert LLVM_IR to MIR:
3371 * o Iterate through the LLVM_IR and construct a graph using
3372 * standard MIR building blocks.
3373 * o Perform a basic-block optimization pass to remove unnecessary
3374 * store/load sequences.
3375 * o Convert the LLVM Value operands into RegLocations where applicable.
3376 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3377 * o Perform register promotion
3378 * o Iterate through the graph a basic block at a time, generating
3379 * LIR.
3380 * o Assemble LIR as usual.
3381 * o Profit.
3382 */
3383void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3384{
buzbeead8f15e2012-06-18 14:49:45 -07003385 llvm::Function* func = cUnit->func;
3386 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003387 // Allocate a list for LIR basic block labels
3388 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07003389 (LIR*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3390 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003391 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003392 for (llvm::Function::iterator i = func->begin(),
3393 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003394 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3395 &labelList[nextLabel++]);
3396 }
buzbeead8f15e2012-06-18 14:49:45 -07003397
3398 /*
3399 * Keep honest - clear regLocations, Value => RegLocation,
3400 * promotion map and VmapTables.
3401 */
3402 cUnit->locMap.clear(); // Start fresh
3403 cUnit->regLocation = NULL;
3404 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3405 i++) {
3406 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3407 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3408 }
3409 cUnit->coreSpillMask = 0;
3410 cUnit->numCoreSpills = 0;
3411 cUnit->fpSpillMask = 0;
3412 cUnit->numFPSpills = 0;
3413 cUnit->coreVmapTable.clear();
3414 cUnit->fpVmapTable.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003415
3416 /*
3417 * At this point, we've lost all knowledge of register promotion.
3418 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003419 * exists - not required for correctness). Normally, this will
3420 * be the first instruction we encounter, so we won't have to iterate
3421 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003422 */
buzbeeca7a5e42012-08-20 11:12:18 -07003423 for (llvm::inst_iterator i = llvm::inst_begin(func),
3424 e = llvm::inst_end(func); i != e; ++i) {
3425 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(&*i);
3426 if (callInst != NULL) {
3427 llvm::Function* callee = callInst->getCalledFunction();
3428 greenland::IntrinsicHelper::IntrinsicId id =
3429 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3430 if (id == greenland::IntrinsicHelper::MethodInfo) {
3431 if (cUnit->printMe) {
3432 LOG(INFO) << "Found MethodInfo";
3433 }
3434 llvm::MDNode* regInfoNode = callInst->getMetadata("RegInfo");
3435 if (regInfoNode != NULL) {
3436 llvm::ConstantInt* numInsValue =
3437 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(0));
3438 llvm::ConstantInt* numRegsValue =
3439 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(1));
3440 llvm::ConstantInt* numOutsValue =
3441 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(2));
3442 llvm::ConstantInt* numCompilerTempsValue =
3443 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(3));
3444 llvm::ConstantInt* numSSARegsValue =
3445 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(4));
3446 if (cUnit->printMe) {
3447 LOG(INFO) << "RegInfo - Ins:" << numInsValue->getZExtValue()
3448 << ", Regs:" << numRegsValue->getZExtValue()
3449 << ", Outs:" << numOutsValue->getZExtValue()
3450 << ", CTemps:" << numCompilerTempsValue->getZExtValue()
3451 << ", SSARegs:" << numSSARegsValue->getZExtValue();
3452 }
3453 }
3454 llvm::MDNode* pmapInfoNode = callInst->getMetadata("PromotionMap");
3455 if (pmapInfoNode != NULL) {
3456 int elems = pmapInfoNode->getNumOperands();
3457 if (cUnit->printMe) {
3458 LOG(INFO) << "PMap size: " << elems;
3459 }
3460 for (int i = 0; i < elems; i++) {
3461 llvm::ConstantInt* rawMapData =
3462 static_cast<llvm::ConstantInt*>(pmapInfoNode->getOperand(i));
3463 uint32_t mapData = rawMapData->getZExtValue();
3464 PromotionMap* p = &cUnit->promotionMap[i];
3465 p->firstInPair = (mapData >> 24) & 0xff;
3466 p->fpReg = (mapData >> 16) & 0xff;
3467 p->coreReg = (mapData >> 8) & 0xff;
3468 p->fpLocation = static_cast<RegLocationType>((mapData >> 4) & 0xf);
3469 if (p->fpLocation == kLocPhysReg) {
3470 oatRecordFpPromotion(cUnit, p->fpReg, i);
3471 }
3472 p->coreLocation = static_cast<RegLocationType>(mapData & 0xf);
3473 if (p->coreLocation == kLocPhysReg) {
3474 oatRecordCorePromotion(cUnit, p->coreReg, i);
3475 }
3476 }
3477 if (cUnit->printMe) {
3478 oatDumpPromotionMap(cUnit);
3479 }
3480 }
3481 break;
3482 }
3483 }
3484 }
3485 oatAdjustSpillMask(cUnit);
3486 cUnit->frameSize = oatComputeFrameSize(cUnit);
buzbeead8f15e2012-06-18 14:49:45 -07003487
3488 // Create RegLocations for arguments
3489 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3490 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3491 for (; it != it_end; ++it) {
3492 llvm::Value* val = it;
3493 createLocFromValue(cUnit, val);
3494 }
3495 // Create RegLocations for all non-argument defintions
3496 for (llvm::inst_iterator i = llvm::inst_begin(func),
3497 e = llvm::inst_end(func); i != e; ++i) {
3498 llvm::Value* val = &*i;
3499 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3500 createLocFromValue(cUnit, val);
3501 }
3502 }
3503
buzbee2cfc6392012-05-07 14:51:40 -07003504 // Walk the blocks, generating code.
3505 for (llvm::Function::iterator i = cUnit->func->begin(),
3506 e = cUnit->func->end(); i != e; ++i) {
3507 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3508 }
3509
3510 handleSuspendLaunchpads(cUnit);
3511
3512 handleThrowLaunchpads(cUnit);
3513
3514 handleIntrinsicLaunchpads(cUnit);
3515
buzbee692be802012-08-29 15:52:59 -07003516 cUnit->func->eraseFromParent();
3517 cUnit->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003518}
3519
3520
3521} // namespace art
3522
3523#endif // ART_USE_QUICK_COMPILER