blob: 9427dcc91d3839be9d201410ea375b3d1b8e03cc [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{
buzbee692be802012-08-29 15:52:59 -0700173 QuickCompiler* quick =
174 reinterpret_cast<QuickCompiler*>(cUnit->compiler->GetCompilerContext());
175 cUnit->context = quick->GetLLVMContext();
176 cUnit->module = quick->GetLLVMModule();
177 cUnit->intrinsic_helper = quick->GetIntrinsicHelper();
178 cUnit->irb = quick->GetIRBuilder();
buzbee2cfc6392012-05-07 14:51:40 -0700179}
180
181const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
182 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
183}
184
buzbeef58c12c2012-07-03 15:06:29 -0700185llvm::BasicBlock* findCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
186{
187 BasicBlock* bb = oatFindBlock(cUnit, vaddr);
188 DCHECK(bb != NULL);
189 return getLLVMBlock(cUnit, bb->id);
190}
191
192void convertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
193 int32_t tableOffset, RegLocation rlSrc)
194{
195 const Instruction::PackedSwitchPayload* payload =
196 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
197 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
198
199 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
200
201 llvm::SwitchInst* sw =
202 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
203 payload->case_count);
204
205 for (uint16_t i = 0; i < payload->case_count; ++i) {
206 llvm::BasicBlock* llvmBB =
207 findCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
208 sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
209 }
210 llvm::MDNode* switchNode =
211 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
212 sw->setMetadata("SwitchTable", switchNode);
213 bb->taken = NULL;
214 bb->fallThrough = NULL;
215}
216
buzbeea1da8a52012-07-09 14:00:21 -0700217void convertSparseSwitch(CompilationUnit* cUnit, BasicBlock* bb,
218 int32_t tableOffset, RegLocation rlSrc)
219{
220 const Instruction::SparseSwitchPayload* payload =
221 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
222 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
223
224 const int32_t* keys = payload->GetKeys();
225 const int32_t* targets = payload->GetTargets();
226
227 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
228
229 llvm::SwitchInst* sw =
230 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
231 payload->case_count);
232
233 for (size_t i = 0; i < payload->case_count; ++i) {
234 llvm::BasicBlock* llvmBB =
235 findCaseTarget(cUnit, cUnit->currentDalvikOffset + targets[i]);
236 sw->addCase(cUnit->irb->getInt32(keys[i]), llvmBB);
237 }
238 llvm::MDNode* switchNode =
239 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
240 sw->setMetadata("SwitchTable", switchNode);
241 bb->taken = NULL;
242 bb->fallThrough = NULL;
243}
244
buzbee8fa0fda2012-06-27 15:44:52 -0700245void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
246 greenland::IntrinsicHelper::IntrinsicId id,
247 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700248{
buzbee8fa0fda2012-06-27 15:44:52 -0700249 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700250 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700251 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
252 defineValue(cUnit, res, rlDest.origSReg);
253}
254
255void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
256 greenland::IntrinsicHelper::IntrinsicId id,
257 RegLocation rlSrc)
258{
259 llvm::SmallVector<llvm::Value*, 2> args;
260 args.push_back(cUnit->irb->getInt32(fieldIndex));
261 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
262 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
263 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700264}
265
buzbee101305f2012-06-28 18:00:56 -0700266void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
267 RegLocation rlArray)
268{
269 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700270 id = greenland::IntrinsicHelper::HLFillArrayData;
buzbee101305f2012-06-28 18:00:56 -0700271 llvm::SmallVector<llvm::Value*, 2> args;
272 args.push_back(cUnit->irb->getInt32(offset));
273 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
274 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
275 cUnit->irb->CreateCall(intr, args);
276}
277
buzbee2cfc6392012-05-07 14:51:40 -0700278llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
279 RegLocation loc)
280{
281 greenland::IntrinsicHelper::IntrinsicId id;
282 if (loc.wide) {
283 if (loc.fp) {
284 id = greenland::IntrinsicHelper::ConstDouble;
285 } else {
286 id = greenland::IntrinsicHelper::ConstLong;
287 }
288 } else {
289 if (loc.fp) {
290 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700291 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700292 id = greenland::IntrinsicHelper::ConstObj;
293 } else {
294 id = greenland::IntrinsicHelper::ConstInt;
295 }
296 }
297 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
298 return cUnit->irb->CreateCall(intr, src);
299}
buzbeeb03f4872012-06-11 15:22:11 -0700300
301void emitPopShadowFrame(CompilationUnit* cUnit)
302{
303 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
304 greenland::IntrinsicHelper::PopShadowFrame);
305 cUnit->irb->CreateCall(intr);
306}
307
buzbee2cfc6392012-05-07 14:51:40 -0700308llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
309 RegLocation loc)
310{
311 greenland::IntrinsicHelper::IntrinsicId id;
312 if (loc.wide) {
313 if (loc.fp) {
314 id = greenland::IntrinsicHelper::CopyDouble;
315 } else {
316 id = greenland::IntrinsicHelper::CopyLong;
317 }
318 } else {
319 if (loc.fp) {
320 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700321 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700322 id = greenland::IntrinsicHelper::CopyObj;
323 } else {
324 id = greenland::IntrinsicHelper::CopyInt;
325 }
326 }
327 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
328 return cUnit->irb->CreateCall(intr, src);
329}
330
buzbee32412962012-06-26 16:27:56 -0700331void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
332{
333 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
334 greenland::IntrinsicHelper::GetException);
335 llvm::Value* res = cUnit->irb->CreateCall(func);
336 defineValue(cUnit, res, rlDest.origSReg);
337}
338
339void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
340{
341 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
342 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
TDYa127f71bf5a2012-07-29 20:09:52 -0700343 greenland::IntrinsicHelper::HLThrowException);
buzbee32412962012-06-26 16:27:56 -0700344 cUnit->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700345}
346
buzbee8fa0fda2012-06-27 15:44:52 -0700347void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
348 greenland::IntrinsicHelper::IntrinsicId id,
349 RegLocation rlSrc)
350{
351 llvm::SmallVector<llvm::Value*, 2> args;
352 args.push_back(cUnit->irb->getInt32(optFlags));
353 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
354 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
355 cUnit->irb->CreateCall(func, args);
356}
357
buzbee76592632012-06-29 15:18:35 -0700358void convertArrayLength(CompilationUnit* cUnit, int optFlags,
359 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700360{
361 llvm::SmallVector<llvm::Value*, 2> args;
362 args.push_back(cUnit->irb->getInt32(optFlags));
363 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
364 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700365 greenland::IntrinsicHelper::OptArrayLength);
buzbee76592632012-06-29 15:18:35 -0700366 llvm::Value* res = cUnit->irb->CreateCall(func, args);
367 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700368}
369
buzbee2cfc6392012-05-07 14:51:40 -0700370void emitSuspendCheck(CompilationUnit* cUnit)
371{
372 greenland::IntrinsicHelper::IntrinsicId id =
373 greenland::IntrinsicHelper::CheckSuspend;
374 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
375 cUnit->irb->CreateCall(intr);
376}
377
378llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
379 llvm::Value* src1, llvm::Value* src2)
380{
381 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700382 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700383 switch(cc) {
384 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
385 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
386 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
387 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
388 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
389 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
390 default: LOG(FATAL) << "Unexpected cc value " << cc;
391 }
392 return res;
393}
394
395void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
396 ConditionCode cc, RegLocation rlSrc1,
397 RegLocation rlSrc2)
398{
399 if (bb->taken->startOffset <= mir->offset) {
400 emitSuspendCheck(cUnit);
401 }
402 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
403 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
404 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
405 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
406 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
407 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700408 // Don't redo the fallthrough branch in the BB driver
409 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700410}
411
412void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
413 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
414{
415 if (bb->taken->startOffset <= mir->offset) {
416 emitSuspendCheck(cUnit);
417 }
418 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
419 llvm::Value* src2;
420 if (rlSrc1.ref) {
421 src2 = cUnit->irb->GetJNull();
422 } else {
423 src2 = cUnit->irb->getInt32(0);
424 }
425 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700426 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
427 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700428 // Don't redo the fallthrough branch in the BB driver
429 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700430}
431
432llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
433 llvm::Value* src1, llvm::Value* src2)
434{
435 greenland::IntrinsicHelper::IntrinsicId id;
436 if (isLong) {
437 if (isDiv) {
438 id = greenland::IntrinsicHelper::DivLong;
439 } else {
440 id = greenland::IntrinsicHelper::RemLong;
441 }
Logan Chien554e6072012-07-23 20:00:01 -0700442 } else {
443 if (isDiv) {
buzbee2cfc6392012-05-07 14:51:40 -0700444 id = greenland::IntrinsicHelper::DivInt;
445 } else {
446 id = greenland::IntrinsicHelper::RemInt;
Logan Chien554e6072012-07-23 20:00:01 -0700447 }
buzbee2cfc6392012-05-07 14:51:40 -0700448 }
449 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
450 llvm::SmallVector<llvm::Value*, 2>args;
451 args.push_back(src1);
452 args.push_back(src2);
453 return cUnit->irb->CreateCall(intr, args);
454}
455
456llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
457 llvm::Value* src1, llvm::Value* src2)
458{
459 llvm::Value* res = NULL;
460 switch(op) {
461 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
462 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700463 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700464 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
465 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
466 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
467 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
468 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
469 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700470 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
471 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
472 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700473 default:
474 LOG(FATAL) << "Invalid op " << op;
475 }
476 return res;
477}
478
479void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
480 RegLocation rlSrc1, RegLocation rlSrc2)
481{
482 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
483 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
484 llvm::Value* res = NULL;
485 switch(op) {
486 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
487 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
488 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
489 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
490 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
491 default:
492 LOG(FATAL) << "Invalid op " << op;
493 }
494 defineValue(cUnit, res, rlDest.origSReg);
495}
496
buzbee2a83e8f2012-07-13 16:42:30 -0700497void convertShift(CompilationUnit* cUnit,
498 greenland::IntrinsicHelper::IntrinsicId id,
499 RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
buzbee4f1181f2012-06-22 13:52:12 -0700500{
buzbee2a83e8f2012-07-13 16:42:30 -0700501 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
502 llvm::SmallVector<llvm::Value*, 2>args;
503 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
504 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
505 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
506 defineValue(cUnit, res, rlDest.origSReg);
507}
508
509void convertShiftLit(CompilationUnit* cUnit,
510 greenland::IntrinsicHelper::IntrinsicId id,
511 RegLocation rlDest, RegLocation rlSrc, int shiftAmount)
512{
513 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
514 llvm::SmallVector<llvm::Value*, 2>args;
515 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
516 args.push_back(cUnit->irb->getInt32(shiftAmount));
517 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700518 defineValue(cUnit, res, rlDest.origSReg);
519}
520
buzbee2cfc6392012-05-07 14:51:40 -0700521void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
522 RegLocation rlSrc1, RegLocation rlSrc2)
523{
524 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
525 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700526 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700527 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
528 defineValue(cUnit, res, rlDest.origSReg);
529}
530
buzbeeb03f4872012-06-11 15:22:11 -0700531void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
532{
533 int index = -1;
534 DCHECK(newVal != NULL);
535 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
536 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
537 if (cUnit->shadowMap[i] == vReg) {
538 index = i;
539 break;
540 }
541 }
TDYa127347166a2012-08-23 12:23:44 -0700542 if (index == -1) {
543 return;
544 }
buzbeeb03f4872012-06-11 15:22:11 -0700545 greenland::IntrinsicHelper::IntrinsicId id =
546 greenland::IntrinsicHelper::SetShadowFrameEntry;
547 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
548 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
549 llvm::Value* args[] = { newVal, tableSlot };
550 cUnit->irb->CreateCall(func, args);
551}
552
buzbee2cfc6392012-05-07 14:51:40 -0700553void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
554 RegLocation rlSrc1, int32_t imm)
555{
556 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
557 llvm::Value* src2 = cUnit->irb->getInt32(imm);
558 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
559 defineValue(cUnit, res, rlDest.origSReg);
560}
561
buzbee101305f2012-06-28 18:00:56 -0700562/*
563 * Process arguments for invoke. Note: this code is also used to
564 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
565 * The requirements are similar.
566 */
buzbee6969d502012-06-15 16:40:31 -0700567void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700568 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700569{
570 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
571 llvm::SmallVector<llvm::Value*, 10> args;
572 // Insert the invokeType
573 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
574 // Insert the method_idx
575 args.push_back(cUnit->irb->getInt32(info->index));
576 // Insert the optimization flags
577 args.push_back(cUnit->irb->getInt32(info->optFlags));
578 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700579 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700580 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
581 args.push_back(val);
582 i += info->args[i].wide ? 2 : 1;
583 }
584 /*
585 * Choose the invoke return type based on actual usage. Note: may
586 * be different than shorty. For example, if a function return value
587 * is not used, we'll treat this as a void invoke.
588 */
589 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700590 if (isFilledNewArray) {
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700591 id = greenland::IntrinsicHelper::HLFilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700592 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700593 id = greenland::IntrinsicHelper::HLInvokeVoid;
594 } else {
595 if (info->result.wide) {
596 if (info->result.fp) {
597 id = greenland::IntrinsicHelper::HLInvokeDouble;
598 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700599 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700600 }
601 } else if (info->result.ref) {
602 id = greenland::IntrinsicHelper::HLInvokeObj;
603 } else if (info->result.fp) {
604 id = greenland::IntrinsicHelper::HLInvokeFloat;
605 } else {
606 id = greenland::IntrinsicHelper::HLInvokeInt;
607 }
608 }
609 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
610 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
611 if (info->result.location != kLocInvalid) {
612 defineValue(cUnit, res, info->result.origSReg);
TDYa127890ea892012-08-22 10:49:42 -0700613 if (info->result.ref) {
614 setShadowFrameEntry(cUnit, (llvm::Value*)
615 cUnit->llvmValues.elemList[info->result.origSReg]);
616 }
buzbee6969d502012-06-15 16:40:31 -0700617 }
618}
619
buzbee101305f2012-06-28 18:00:56 -0700620void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
621 greenland::IntrinsicHelper::IntrinsicId id,
622 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700623{
buzbee6969d502012-06-15 16:40:31 -0700624 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700625 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700626 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
627 defineValue(cUnit, res, rlDest.origSReg);
628}
629
buzbee101305f2012-06-28 18:00:56 -0700630void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
631 RegLocation rlSrc)
632{
633 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700634 id = greenland::IntrinsicHelper::HLCheckCast;
buzbee101305f2012-06-28 18:00:56 -0700635 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
636 llvm::SmallVector<llvm::Value*, 2> args;
637 args.push_back(cUnit->irb->getInt32(type_idx));
638 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
639 cUnit->irb->CreateCall(intr, args);
640}
641
buzbee8fa0fda2012-06-27 15:44:52 -0700642void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
643 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700644{
645 greenland::IntrinsicHelper::IntrinsicId id;
646 id = greenland::IntrinsicHelper::NewInstance;
647 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
648 llvm::Value* index = cUnit->irb->getInt32(type_idx);
649 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
650 defineValue(cUnit, res, rlDest.origSReg);
651}
652
buzbee8fa0fda2012-06-27 15:44:52 -0700653void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
654 RegLocation rlDest, RegLocation rlSrc)
655{
656 greenland::IntrinsicHelper::IntrinsicId id;
657 id = greenland::IntrinsicHelper::NewArray;
658 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
659 llvm::SmallVector<llvm::Value*, 2> args;
660 args.push_back(cUnit->irb->getInt32(type_idx));
661 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
662 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
663 defineValue(cUnit, res, rlDest.origSReg);
664}
665
666void convertAget(CompilationUnit* cUnit, int optFlags,
667 greenland::IntrinsicHelper::IntrinsicId id,
668 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
669{
670 llvm::SmallVector<llvm::Value*, 3> args;
671 args.push_back(cUnit->irb->getInt32(optFlags));
672 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
673 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
674 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
675 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
676 defineValue(cUnit, res, rlDest.origSReg);
677}
678
679void convertAput(CompilationUnit* cUnit, int optFlags,
680 greenland::IntrinsicHelper::IntrinsicId id,
681 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
682{
683 llvm::SmallVector<llvm::Value*, 4> args;
684 args.push_back(cUnit->irb->getInt32(optFlags));
685 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
686 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
687 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
688 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
689 cUnit->irb->CreateCall(intr, args);
690}
691
buzbee101305f2012-06-28 18:00:56 -0700692void convertIget(CompilationUnit* cUnit, int optFlags,
693 greenland::IntrinsicHelper::IntrinsicId id,
694 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
695{
696 llvm::SmallVector<llvm::Value*, 3> args;
697 args.push_back(cUnit->irb->getInt32(optFlags));
698 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
699 args.push_back(cUnit->irb->getInt32(fieldIndex));
700 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
701 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
702 defineValue(cUnit, res, rlDest.origSReg);
703}
704
705void convertIput(CompilationUnit* cUnit, int optFlags,
706 greenland::IntrinsicHelper::IntrinsicId id,
707 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
708{
709 llvm::SmallVector<llvm::Value*, 4> args;
710 args.push_back(cUnit->irb->getInt32(optFlags));
711 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
712 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
713 args.push_back(cUnit->irb->getInt32(fieldIndex));
714 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
715 cUnit->irb->CreateCall(intr, args);
716}
717
buzbee8fa0fda2012-06-27 15:44:52 -0700718void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
719 RegLocation rlDest, RegLocation rlSrc)
720{
721 greenland::IntrinsicHelper::IntrinsicId id;
722 id = greenland::IntrinsicHelper::InstanceOf;
723 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
724 llvm::SmallVector<llvm::Value*, 2> args;
725 args.push_back(cUnit->irb->getInt32(type_idx));
726 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
727 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
728 defineValue(cUnit, res, rlDest.origSReg);
729}
730
buzbee101305f2012-06-28 18:00:56 -0700731void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
732 RegLocation rlSrc)
733{
734 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
735 cUnit->irb->getInt64Ty());
736 defineValue(cUnit, res, rlDest.origSReg);
737}
738
buzbee76592632012-06-29 15:18:35 -0700739void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
740 RegLocation rlSrc)
741{
742 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
743 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
744 defineValue(cUnit, res, rlDest.origSReg);
745}
746
747void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
748 RegLocation rlSrc)
749{
750 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
751 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
752 defineValue(cUnit, res, rlDest.origSReg);
753}
754
755void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
756 RegLocation rlSrc)
757{
758 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
759 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
760 defineValue(cUnit, res, rlDest.origSReg);
761}
762
763void convertWideComparison(CompilationUnit* cUnit,
764 greenland::IntrinsicHelper::IntrinsicId id,
765 RegLocation rlDest, RegLocation rlSrc1,
766 RegLocation rlSrc2)
767{
768 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
769 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
770 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
771 llvm::SmallVector<llvm::Value*, 2> args;
772 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
773 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
774 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
775 defineValue(cUnit, res, rlDest.origSReg);
776}
777
buzbee101305f2012-06-28 18:00:56 -0700778void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
779 RegLocation rlSrc,
780 greenland::IntrinsicHelper::IntrinsicId id)
781{
782 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700783 llvm::Value* res =
784 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
785 defineValue(cUnit, res, rlDest.origSReg);
786}
787
788void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
789 RegLocation rlSrc)
790{
791 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
792 defineValue(cUnit, res, rlDest.origSReg);
793}
794
795void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
796 RegLocation rlSrc)
797{
798 llvm::Value* res =
799 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
800 defineValue(cUnit, res, rlDest.origSReg);
801}
802
TDYa1274ec8ccd2012-08-11 07:04:57 -0700803void convertFPToInt(CompilationUnit* cUnit,
804 greenland::IntrinsicHelper::IntrinsicId id,
805 RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700806 RegLocation rlSrc)
807{
TDYa1274ec8ccd2012-08-11 07:04:57 -0700808 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
809 llvm::Value* res = cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
buzbee76592632012-06-29 15:18:35 -0700810 defineValue(cUnit, res, rlDest.origSReg);
811}
812
813
814void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
815 RegLocation rlSrc)
816{
817 llvm::Value* res =
818 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
819 defineValue(cUnit, res, rlDest.origSReg);
820}
821
822void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
823 RegLocation rlSrc)
824{
825 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
826 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700827 defineValue(cUnit, res, rlDest.origSReg);
828}
829
buzbee2cfc6392012-05-07 14:51:40 -0700830/*
831 * Target-independent code generation. Use only high-level
832 * load/store utilities here, or target-dependent genXX() handlers
833 * when necessary.
834 */
835bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
836 llvm::BasicBlock* llvmBB, LIR* labelList)
837{
838 bool res = false; // Assume success
839 RegLocation rlSrc[3];
840 RegLocation rlDest = badLoc;
buzbee2cfc6392012-05-07 14:51:40 -0700841 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee6969d502012-06-15 16:40:31 -0700842 uint32_t vB = mir->dalvikInsn.vB;
843 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700844 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700845
buzbeeb03f4872012-06-11 15:22:11 -0700846 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700847
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700848 if (cUnit->printMe) {
849 if ((int)opcode < kMirOpFirst) {
850 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x"
851 << std::hex << (int)opcode;
852 } else {
853 LOG(INFO) << ".. opcode 0x" << std::hex << (int)opcode;
854 }
855 }
856
buzbee2cfc6392012-05-07 14:51:40 -0700857 /* Prep Src and Dest locations */
858 int nextSreg = 0;
859 int nextLoc = 0;
860 int attrs = oatDataFlowAttributes[opcode];
861 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
862 if (attrs & DF_UA) {
863 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700864 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700865 nextSreg+= 2;
866 } else {
867 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
868 nextSreg++;
869 }
870 }
871 if (attrs & DF_UB) {
872 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700873 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700874 nextSreg+= 2;
875 } else {
876 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
877 nextSreg++;
878 }
879 }
880 if (attrs & DF_UC) {
881 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700882 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700883 } else {
884 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
885 }
886 }
887 if (attrs & DF_DA) {
888 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700889 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700890 } else {
buzbee15bf9802012-06-12 17:49:27 -0700891 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700892 if (rlDest.ref) {
893 objectDefinition = true;
894 }
buzbee2cfc6392012-05-07 14:51:40 -0700895 }
896 }
897
898 switch (opcode) {
899 case Instruction::NOP:
900 break;
901
902 case Instruction::MOVE:
903 case Instruction::MOVE_OBJECT:
904 case Instruction::MOVE_16:
905 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700906 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700907 case Instruction::MOVE_FROM16:
908 case Instruction::MOVE_WIDE:
909 case Instruction::MOVE_WIDE_16:
910 case Instruction::MOVE_WIDE_FROM16: {
911 /*
912 * Moves/copies are meaningless in pure SSA register form,
913 * but we need to preserve them for the conversion back into
914 * MIR (at least until we stop using the Dalvik register maps).
915 * Insert a dummy intrinsic copy call, which will be recognized
916 * by the quick path and removed by the portable path.
917 */
918 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
919 llvm::Value* res = emitCopy(cUnit, src, rlDest);
920 defineValue(cUnit, res, rlDest.origSReg);
921 }
922 break;
923
924 case Instruction::CONST:
925 case Instruction::CONST_4:
926 case Instruction::CONST_16: {
TDYa127347166a2012-08-23 12:23:44 -0700927 if (vB == 0) {
928 objectDefinition = true;
929 }
buzbee6969d502012-06-15 16:40:31 -0700930 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700931 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
932 defineValue(cUnit, res, rlDest.origSReg);
933 }
934 break;
935
936 case Instruction::CONST_WIDE_16:
937 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700938 // Sign extend to 64 bits
939 int64_t imm = static_cast<int32_t>(vB);
940 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700941 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
942 defineValue(cUnit, res, rlDest.origSReg);
943 }
944 break;
945
946 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700947 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700948 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
949 defineValue(cUnit, res, rlDest.origSReg);
950 }
951 break;
952
953 case Instruction::CONST_WIDE: {
954 llvm::Constant* immValue =
955 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
956 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
957 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700958 }
959 break;
buzbee2cfc6392012-05-07 14:51:40 -0700960 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700961 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700962 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
963 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
964 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700965 }
966 break;
967
buzbee8fa0fda2012-06-27 15:44:52 -0700968 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700969 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700970 rlSrc[0]);
971 break;
972 case Instruction::SPUT:
973 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700974 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700975 rlSrc[0]);
976 } else {
buzbee76592632012-06-29 15:18:35 -0700977 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700978 }
979 break;
980 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700981 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700982 rlSrc[0]);
983 break;
984 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700985 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700986 break;
987 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700988 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700989 break;
990 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -0700991 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700992 break;
993 case Instruction::SPUT_WIDE:
994 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700995 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -0700996 rlSrc[0]);
997 } else {
buzbee76592632012-06-29 15:18:35 -0700998 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -0700999 rlSrc[0]);
1000 }
1001 break;
1002
1003 case Instruction::SGET_OBJECT:
1004 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
1005 break;
1006 case Instruction::SGET:
1007 if (rlDest.fp) {
1008 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
1009 } else {
1010 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
1011 }
1012 break;
1013 case Instruction::SGET_BOOLEAN:
1014 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
1015 break;
1016 case Instruction::SGET_BYTE:
1017 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
1018 break;
1019 case Instruction::SGET_CHAR:
1020 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
1021 break;
1022 case Instruction::SGET_SHORT:
1023 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
1024 break;
1025 case Instruction::SGET_WIDE:
1026 if (rlDest.fp) {
1027 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
1028 rlDest);
1029 } else {
1030 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001031 }
1032 break;
buzbee2cfc6392012-05-07 14:51:40 -07001033
1034 case Instruction::RETURN_WIDE:
1035 case Instruction::RETURN:
1036 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -07001037 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001038 emitSuspendCheck(cUnit);
1039 }
buzbeeb03f4872012-06-11 15:22:11 -07001040 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001041 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
1042 bb->hasReturn = true;
1043 }
1044 break;
1045
1046 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001047 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001048 emitSuspendCheck(cUnit);
1049 }
buzbeeb03f4872012-06-11 15:22:11 -07001050 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001051 cUnit->irb->CreateRetVoid();
1052 bb->hasReturn = true;
1053 }
1054 break;
1055
1056 case Instruction::IF_EQ:
1057 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1058 break;
1059 case Instruction::IF_NE:
1060 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1061 break;
1062 case Instruction::IF_LT:
1063 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1064 break;
1065 case Instruction::IF_GE:
1066 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1067 break;
1068 case Instruction::IF_GT:
1069 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1070 break;
1071 case Instruction::IF_LE:
1072 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1073 break;
1074 case Instruction::IF_EQZ:
1075 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1076 break;
1077 case Instruction::IF_NEZ:
1078 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1079 break;
1080 case Instruction::IF_LTZ:
1081 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1082 break;
1083 case Instruction::IF_GEZ:
1084 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1085 break;
1086 case Instruction::IF_GTZ:
1087 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1088 break;
1089 case Instruction::IF_LEZ:
1090 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1091 break;
1092
1093 case Instruction::GOTO:
1094 case Instruction::GOTO_16:
1095 case Instruction::GOTO_32: {
1096 if (bb->taken->startOffset <= bb->startOffset) {
1097 emitSuspendCheck(cUnit);
1098 }
1099 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1100 }
1101 break;
1102
1103 case Instruction::ADD_LONG:
1104 case Instruction::ADD_LONG_2ADDR:
1105 case Instruction::ADD_INT:
1106 case Instruction::ADD_INT_2ADDR:
1107 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1108 break;
1109 case Instruction::SUB_LONG:
1110 case Instruction::SUB_LONG_2ADDR:
1111 case Instruction::SUB_INT:
1112 case Instruction::SUB_INT_2ADDR:
1113 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1114 break;
1115 case Instruction::MUL_LONG:
1116 case Instruction::MUL_LONG_2ADDR:
1117 case Instruction::MUL_INT:
1118 case Instruction::MUL_INT_2ADDR:
1119 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1120 break;
1121 case Instruction::DIV_LONG:
1122 case Instruction::DIV_LONG_2ADDR:
1123 case Instruction::DIV_INT:
1124 case Instruction::DIV_INT_2ADDR:
1125 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1126 break;
1127 case Instruction::REM_LONG:
1128 case Instruction::REM_LONG_2ADDR:
1129 case Instruction::REM_INT:
1130 case Instruction::REM_INT_2ADDR:
1131 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1132 break;
1133 case Instruction::AND_LONG:
1134 case Instruction::AND_LONG_2ADDR:
1135 case Instruction::AND_INT:
1136 case Instruction::AND_INT_2ADDR:
1137 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1138 break;
1139 case Instruction::OR_LONG:
1140 case Instruction::OR_LONG_2ADDR:
1141 case Instruction::OR_INT:
1142 case Instruction::OR_INT_2ADDR:
1143 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1144 break;
1145 case Instruction::XOR_LONG:
1146 case Instruction::XOR_LONG_2ADDR:
1147 case Instruction::XOR_INT:
1148 case Instruction::XOR_INT_2ADDR:
1149 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1150 break;
1151 case Instruction::SHL_LONG:
1152 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001153 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1154 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001155 break;
buzbee2cfc6392012-05-07 14:51:40 -07001156 case Instruction::SHL_INT:
1157 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001158 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1159 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001160 break;
1161 case Instruction::SHR_LONG:
1162 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001163 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1164 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001165 break;
buzbee2cfc6392012-05-07 14:51:40 -07001166 case Instruction::SHR_INT:
1167 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001168 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1169 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001170 break;
1171 case Instruction::USHR_LONG:
1172 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001173 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1174 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001175 break;
buzbee2cfc6392012-05-07 14:51:40 -07001176 case Instruction::USHR_INT:
1177 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001178 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1179 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001180 break;
1181
1182 case Instruction::ADD_INT_LIT16:
1183 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001184 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001185 break;
1186 case Instruction::RSUB_INT:
1187 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001188 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001189 break;
1190 case Instruction::MUL_INT_LIT16:
1191 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001192 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001193 break;
1194 case Instruction::DIV_INT_LIT16:
1195 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001196 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001197 break;
1198 case Instruction::REM_INT_LIT16:
1199 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001200 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001201 break;
1202 case Instruction::AND_INT_LIT16:
1203 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001204 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001205 break;
1206 case Instruction::OR_INT_LIT16:
1207 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001208 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001209 break;
1210 case Instruction::XOR_INT_LIT16:
1211 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001212 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001213 break;
1214 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001215 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1216 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001217 break;
1218 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001219 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1220 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001221 break;
1222 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001223 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1224 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001225 break;
1226
1227 case Instruction::ADD_FLOAT:
1228 case Instruction::ADD_FLOAT_2ADDR:
1229 case Instruction::ADD_DOUBLE:
1230 case Instruction::ADD_DOUBLE_2ADDR:
1231 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1232 break;
1233
1234 case Instruction::SUB_FLOAT:
1235 case Instruction::SUB_FLOAT_2ADDR:
1236 case Instruction::SUB_DOUBLE:
1237 case Instruction::SUB_DOUBLE_2ADDR:
1238 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1239 break;
1240
1241 case Instruction::MUL_FLOAT:
1242 case Instruction::MUL_FLOAT_2ADDR:
1243 case Instruction::MUL_DOUBLE:
1244 case Instruction::MUL_DOUBLE_2ADDR:
1245 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1246 break;
1247
1248 case Instruction::DIV_FLOAT:
1249 case Instruction::DIV_FLOAT_2ADDR:
1250 case Instruction::DIV_DOUBLE:
1251 case Instruction::DIV_DOUBLE_2ADDR:
1252 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1253 break;
1254
1255 case Instruction::REM_FLOAT:
1256 case Instruction::REM_FLOAT_2ADDR:
1257 case Instruction::REM_DOUBLE:
1258 case Instruction::REM_DOUBLE_2ADDR:
1259 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1260 break;
1261
buzbee6969d502012-06-15 16:40:31 -07001262 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001263 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1264 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001265 break;
1266 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001267 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1268 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001269 break;
1270
1271 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001272 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1273 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001274 break;
1275 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001276 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1277 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001278 break;
1279
1280 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001281 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1282 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001283 break;
1284 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001285 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1286 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001287 break;
1288
1289 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001290 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1291 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001292 break;
1293 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001294 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1295 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001296 break;
1297
1298 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001299 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1300 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001301 break;
1302 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001303 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1304 false /* NewFilledArray */);
1305 break;
1306 case Instruction::FILLED_NEW_ARRAY:
1307 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1308 true /* NewFilledArray */);
1309 break;
1310 case Instruction::FILLED_NEW_ARRAY_RANGE:
1311 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1312 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001313 break;
1314
1315 case Instruction::CONST_STRING:
1316 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001317 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1318 rlDest);
1319 break;
1320
1321 case Instruction::CONST_CLASS:
1322 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1323 rlDest);
1324 break;
1325
1326 case Instruction::CHECK_CAST:
1327 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001328 break;
1329
buzbee4f1181f2012-06-22 13:52:12 -07001330 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001331 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001332 break;
1333
buzbee32412962012-06-26 16:27:56 -07001334 case Instruction::MOVE_EXCEPTION:
1335 convertMoveException(cUnit, rlDest);
1336 break;
1337
1338 case Instruction::THROW:
1339 convertThrow(cUnit, rlSrc[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001340 /*
1341 * If this throw is standalone, terminate.
1342 * If it might rethrow, force termination
1343 * of the following block.
1344 */
1345 if (bb->fallThrough == NULL) {
1346 cUnit->irb->CreateUnreachable();
1347 } else {
1348 bb->fallThrough->fallThrough = NULL;
1349 bb->fallThrough->taken = NULL;
1350 }
buzbee32412962012-06-26 16:27:56 -07001351 break;
1352
buzbee2cfc6392012-05-07 14:51:40 -07001353 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001354 case Instruction::MOVE_RESULT:
1355 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001356 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001357 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001358 */
jeffhao9a4f0032012-08-30 16:17:40 -07001359 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001360 break;
1361
1362 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001363 convertMonitorEnterExit(cUnit, optFlags,
1364 greenland::IntrinsicHelper::MonitorEnter,
1365 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001366 break;
1367
1368 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001369 convertMonitorEnterExit(cUnit, optFlags,
1370 greenland::IntrinsicHelper::MonitorExit,
1371 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001372 break;
1373
1374 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001375 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001376 break;
1377
1378 case Instruction::NEW_ARRAY:
1379 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1380 break;
1381
1382 case Instruction::INSTANCE_OF:
1383 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1384 break;
1385
1386 case Instruction::AGET:
1387 if (rlDest.fp) {
1388 convertAget(cUnit, optFlags,
1389 greenland::IntrinsicHelper::HLArrayGetFloat,
1390 rlDest, rlSrc[0], rlSrc[1]);
1391 } else {
1392 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1393 rlDest, rlSrc[0], rlSrc[1]);
1394 }
1395 break;
1396 case Instruction::AGET_OBJECT:
1397 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1398 rlDest, rlSrc[0], rlSrc[1]);
1399 break;
1400 case Instruction::AGET_BOOLEAN:
1401 convertAget(cUnit, optFlags,
1402 greenland::IntrinsicHelper::HLArrayGetBoolean,
1403 rlDest, rlSrc[0], rlSrc[1]);
1404 break;
1405 case Instruction::AGET_BYTE:
1406 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1407 rlDest, rlSrc[0], rlSrc[1]);
1408 break;
1409 case Instruction::AGET_CHAR:
1410 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1411 rlDest, rlSrc[0], rlSrc[1]);
1412 break;
1413 case Instruction::AGET_SHORT:
1414 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1415 rlDest, rlSrc[0], rlSrc[1]);
1416 break;
1417 case Instruction::AGET_WIDE:
1418 if (rlDest.fp) {
1419 convertAget(cUnit, optFlags,
1420 greenland::IntrinsicHelper::HLArrayGetDouble,
1421 rlDest, rlSrc[0], rlSrc[1]);
1422 } else {
1423 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1424 rlDest, rlSrc[0], rlSrc[1]);
1425 }
1426 break;
1427
1428 case Instruction::APUT:
1429 if (rlSrc[0].fp) {
1430 convertAput(cUnit, optFlags,
1431 greenland::IntrinsicHelper::HLArrayPutFloat,
1432 rlSrc[0], rlSrc[1], rlSrc[2]);
1433 } else {
1434 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1435 rlSrc[0], rlSrc[1], rlSrc[2]);
1436 }
1437 break;
1438 case Instruction::APUT_OBJECT:
1439 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1440 rlSrc[0], rlSrc[1], rlSrc[2]);
1441 break;
1442 case Instruction::APUT_BOOLEAN:
1443 convertAput(cUnit, optFlags,
1444 greenland::IntrinsicHelper::HLArrayPutBoolean,
1445 rlSrc[0], rlSrc[1], rlSrc[2]);
1446 break;
1447 case Instruction::APUT_BYTE:
1448 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1449 rlSrc[0], rlSrc[1], rlSrc[2]);
1450 break;
1451 case Instruction::APUT_CHAR:
1452 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1453 rlSrc[0], rlSrc[1], rlSrc[2]);
1454 break;
1455 case Instruction::APUT_SHORT:
1456 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1457 rlSrc[0], rlSrc[1], rlSrc[2]);
1458 break;
1459 case Instruction::APUT_WIDE:
1460 if (rlSrc[0].fp) {
1461 convertAput(cUnit, optFlags,
1462 greenland::IntrinsicHelper::HLArrayPutDouble,
1463 rlSrc[0], rlSrc[1], rlSrc[2]);
1464 } else {
1465 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1466 rlSrc[0], rlSrc[1], rlSrc[2]);
1467 }
1468 break;
1469
buzbee101305f2012-06-28 18:00:56 -07001470 case Instruction::IGET:
1471 if (rlDest.fp) {
1472 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001473 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001474 } else {
1475 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001476 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001477 }
buzbee2cfc6392012-05-07 14:51:40 -07001478 break;
buzbee101305f2012-06-28 18:00:56 -07001479 case Instruction::IGET_OBJECT:
1480 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001481 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001482 break;
1483 case Instruction::IGET_BOOLEAN:
1484 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001485 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001486 break;
1487 case Instruction::IGET_BYTE:
1488 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001489 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001490 break;
1491 case Instruction::IGET_CHAR:
1492 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001493 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001494 break;
1495 case Instruction::IGET_SHORT:
1496 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001497 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001498 break;
1499 case Instruction::IGET_WIDE:
1500 if (rlDest.fp) {
1501 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001502 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001503 } else {
1504 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001505 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001506 }
1507 break;
1508 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001509 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001510 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1511 rlSrc[0], rlSrc[1], vC);
1512 } else {
1513 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1514 rlSrc[0], rlSrc[1], vC);
1515 }
1516 break;
1517 case Instruction::IPUT_OBJECT:
1518 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1519 rlSrc[0], rlSrc[1], vC);
1520 break;
1521 case Instruction::IPUT_BOOLEAN:
1522 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1523 rlSrc[0], rlSrc[1], vC);
1524 break;
1525 case Instruction::IPUT_BYTE:
1526 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1527 rlSrc[0], rlSrc[1], vC);
1528 break;
1529 case Instruction::IPUT_CHAR:
1530 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1531 rlSrc[0], rlSrc[1], vC);
1532 break;
1533 case Instruction::IPUT_SHORT:
1534 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1535 rlSrc[0], rlSrc[1], vC);
1536 break;
1537 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001538 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001539 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1540 rlSrc[0], rlSrc[1], vC);
1541 } else {
1542 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1543 rlSrc[0], rlSrc[1], vC);
1544 }
buzbee2cfc6392012-05-07 14:51:40 -07001545 break;
1546
1547 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001548 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001549 break;
1550
buzbee76592632012-06-29 15:18:35 -07001551 case Instruction::LONG_TO_INT:
1552 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1553 break;
1554
buzbee101305f2012-06-28 18:00:56 -07001555 case Instruction::INT_TO_LONG:
1556 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001557 break;
1558
buzbee101305f2012-06-28 18:00:56 -07001559 case Instruction::INT_TO_CHAR:
1560 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1561 greenland::IntrinsicHelper::IntToChar);
1562 break;
1563 case Instruction::INT_TO_BYTE:
1564 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1565 greenland::IntrinsicHelper::IntToByte);
1566 break;
1567 case Instruction::INT_TO_SHORT:
1568 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1569 greenland::IntrinsicHelper::IntToShort);
1570 break;
1571
buzbee76592632012-06-29 15:18:35 -07001572 case Instruction::INT_TO_FLOAT:
1573 case Instruction::LONG_TO_FLOAT:
1574 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001575 break;
1576
buzbee76592632012-06-29 15:18:35 -07001577 case Instruction::INT_TO_DOUBLE:
1578 case Instruction::LONG_TO_DOUBLE:
1579 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001580 break;
1581
buzbee76592632012-06-29 15:18:35 -07001582 case Instruction::FLOAT_TO_DOUBLE:
1583 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001584 break;
1585
buzbee76592632012-06-29 15:18:35 -07001586 case Instruction::DOUBLE_TO_FLOAT:
1587 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001588 break;
1589
1590 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001591 case Instruction::NEG_INT:
1592 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001593 break;
1594
1595 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001596 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001597 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001598 break;
1599
buzbee76592632012-06-29 15:18:35 -07001600 case Instruction::NOT_LONG:
1601 case Instruction::NOT_INT:
1602 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001603 break;
1604
buzbee2cfc6392012-05-07 14:51:40 -07001605 case Instruction::FLOAT_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001606 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2I, rlDest, rlSrc[0]);
1607 break;
1608
buzbee2cfc6392012-05-07 14:51:40 -07001609 case Instruction::DOUBLE_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001610 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2I, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001611 break;
1612
buzbee76592632012-06-29 15:18:35 -07001613 case Instruction::FLOAT_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001614 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2L, rlDest, rlSrc[0]);
1615 break;
1616
buzbee76592632012-06-29 15:18:35 -07001617 case Instruction::DOUBLE_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001618 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2L, rlDest, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001619 break;
1620
1621 case Instruction::CMPL_FLOAT:
1622 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1623 rlDest, rlSrc[0], rlSrc[1]);
1624 break;
1625 case Instruction::CMPG_FLOAT:
1626 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1627 rlDest, rlSrc[0], rlSrc[1]);
1628 break;
1629 case Instruction::CMPL_DOUBLE:
1630 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1631 rlDest, rlSrc[0], rlSrc[1]);
1632 break;
1633 case Instruction::CMPG_DOUBLE:
1634 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1635 rlDest, rlSrc[0], rlSrc[1]);
1636 break;
1637 case Instruction::CMP_LONG:
1638 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1639 rlDest, rlSrc[0], rlSrc[1]);
1640 break;
1641
buzbee76592632012-06-29 15:18:35 -07001642 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001643 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001644 break;
1645
1646 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001647 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001648 break;
buzbee2cfc6392012-05-07 14:51:40 -07001649
1650 default:
buzbee32412962012-06-26 16:27:56 -07001651 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001652 res = true;
1653 }
buzbeeb03f4872012-06-11 15:22:11 -07001654 if (objectDefinition) {
1655 setShadowFrameEntry(cUnit, (llvm::Value*)
1656 cUnit->llvmValues.elemList[rlDest.origSReg]);
1657 }
buzbee2cfc6392012-05-07 14:51:40 -07001658 return res;
1659}
1660
1661/* Extended MIR instructions like PHI */
1662void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1663 llvm::BasicBlock* llvmBB)
1664{
1665
1666 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1667 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001668 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001669 /*
1670 * The Art compiler's Phi nodes only handle 32-bit operands,
1671 * representing wide values using a matched set of Phi nodes
1672 * for the lower and upper halves. In the llvm world, we only
1673 * want a single Phi for wides. Here we will simply discard
1674 * the Phi node representing the high word.
1675 */
1676 if (rlDest.highWord) {
1677 return; // No Phi node - handled via low word
1678 }
1679 int* incoming = (int*)mir->dalvikInsn.vB;
buzbee2cfc6392012-05-07 14:51:40 -07001680 llvm::Type* phiType =
1681 llvmTypeFromLocRec(cUnit, rlDest);
1682 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1683 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1684 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001685 // Don't check width here.
1686 loc = oatGetRawSrc(cUnit, mir, i);
1687 DCHECK_EQ(rlDest.wide, loc.wide);
1688 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1689 DCHECK_EQ(rlDest.fp, loc.fp);
1690 DCHECK_EQ(rlDest.core, loc.core);
1691 DCHECK_EQ(rlDest.ref, loc.ref);
buzbeed1643e42012-09-05 14:06:51 -07001692 SafeMap<unsigned int, unsigned int>::iterator it;
1693 it = cUnit->blockIdMap.find(incoming[i]);
1694 DCHECK(it != cUnit->blockIdMap.end());
buzbee2cfc6392012-05-07 14:51:40 -07001695 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
buzbeed1643e42012-09-05 14:06:51 -07001696 getLLVMBlock(cUnit, it->second));
buzbee2cfc6392012-05-07 14:51:40 -07001697 }
1698 defineValue(cUnit, phi, rlDest.origSReg);
1699 break;
1700 }
1701 case kMirOpCopy: {
1702 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1703 break;
1704 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001705 case kMirOpNop:
1706 if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
1707 (bb->fallThrough == NULL)) {
1708 cUnit->irb->CreateUnreachable();
1709 }
1710 break;
1711
buzbee2cfc6392012-05-07 14:51:40 -07001712#if defined(TARGET_ARM)
1713 case kMirOpFusedCmplFloat:
1714 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1715 break;
1716 case kMirOpFusedCmpgFloat:
1717 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1718 break;
1719 case kMirOpFusedCmplDouble:
1720 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1721 break;
1722 case kMirOpFusedCmpgDouble:
1723 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1724 break;
1725 case kMirOpFusedCmpLong:
1726 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1727 break;
1728#endif
1729 default:
1730 break;
1731 }
1732}
1733
1734void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1735{
1736 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001737 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001738 arrayRef.push_back(cUnit->irb->getInt32(offset));
1739 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1740 cUnit->irb->SetDexOffset(node);
1741}
1742
1743// Attach method info as metadata to special intrinsic
1744void setMethodInfo(CompilationUnit* cUnit)
1745{
1746 // We don't want dex offset on this
1747 cUnit->irb->SetDexOffset(NULL);
1748 greenland::IntrinsicHelper::IntrinsicId id;
1749 id = greenland::IntrinsicHelper::MethodInfo;
1750 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1751 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1752 llvm::SmallVector<llvm::Value*, 2> regInfo;
1753 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1754 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1755 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1756 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1757 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1758 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1759 inst->setMetadata("RegInfo", regInfoNode);
1760 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1761 llvm::SmallVector<llvm::Value*, 50> pmap;
1762 for (int i = 0; i < promoSize; i++) {
1763 PromotionMap* p = &cUnit->promotionMap[i];
1764 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1765 ((p->fpReg & 0xff) << 16) |
1766 ((p->coreReg & 0xff) << 8) |
1767 ((p->fpLocation & 0xf) << 4) |
1768 (p->coreLocation & 0xf);
1769 pmap.push_back(cUnit->irb->getInt32(mapData));
1770 }
1771 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1772 inst->setMetadata("PromotionMap", mapNode);
1773 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1774}
1775
1776/* Handle the content in each basic block */
1777bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1778{
buzbeed1643e42012-09-05 14:06:51 -07001779 if (bb->blockType == kDead) return false;
buzbee2cfc6392012-05-07 14:51:40 -07001780 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
Shih-wei Liao21d28f52012-06-12 05:55:00 -07001781 if (llvmBB != NULL) {
1782 cUnit->irb->SetInsertPoint(llvmBB);
1783 setDexOffset(cUnit, bb->startOffset);
1784 }
buzbee2cfc6392012-05-07 14:51:40 -07001785
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001786 if (cUnit->printMe) {
1787 LOG(INFO) << "................................";
1788 LOG(INFO) << "Block id " << bb->id;
1789 if (llvmBB != NULL) {
1790 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1791 } else {
1792 LOG(INFO) << "llvmBB is NULL";
1793 }
1794 }
1795
buzbee2cfc6392012-05-07 14:51:40 -07001796 if (bb->blockType == kEntryBlock) {
1797 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001798 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1799 cUnit->numDalvikRegisters, true,
1800 kAllocMisc);
1801 for (int i = 0; i < cUnit->numSSARegs; i++) {
1802 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1803 }
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