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