blob: a9e134f287e7692702833ac971c2ea69527333f8 [file] [log] [blame]
buzbee2cfc6392012-05-07 14:51:40 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#if defined(ART_USE_QUICK_COMPILER)
buzbee2cfc6392012-05-07 14:51:40 -070018#include "object_utils.h"
19
20#include <llvm/Support/ToolOutputFile.h>
21#include <llvm/Bitcode/ReaderWriter.h>
22#include <llvm/Analysis/Verifier.h>
23#include <llvm/Metadata.h>
24#include <llvm/ADT/DepthFirstIterator.h>
25#include <llvm/Instruction.h>
26#include <llvm/Type.h>
27#include <llvm/Instructions.h>
28#include <llvm/Support/Casting.h>
buzbeead8f15e2012-06-18 14:49:45 -070029#include <llvm/Support/InstIterator.h>
buzbee2cfc6392012-05-07 14:51:40 -070030
buzbee8320f382012-09-11 16:29:42 -070031static const char* kLabelFormat = "%c0x%x_%d";
32static const char kNormalBlock = 'L';
33static const char kCatchBlock = 'C';
buzbee2cfc6392012-05-07 14:51:40 -070034
35namespace art {
36extern const RegLocation badLoc;
buzbeeb03f4872012-06-11 15:22:11 -070037RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070038
39llvm::BasicBlock* getLLVMBlock(CompilationUnit* cUnit, int id)
40{
41 return cUnit->idToBlockMap.Get(id);
42}
43
44llvm::Value* getLLVMValue(CompilationUnit* cUnit, int sReg)
45{
46 return (llvm::Value*)oatGrowableListGetElement(&cUnit->llvmValues, sReg);
47}
48
49// Replace the placeholder value with the real definition
50void defineValue(CompilationUnit* cUnit, llvm::Value* val, int sReg)
51{
52 llvm::Value* placeholder = getLLVMValue(cUnit, sReg);
buzbee9a2487f2012-07-26 14:01:13 -070053 if (placeholder == NULL) {
54 // This can happen on instruction rewrite on verification failure
Bill Buzbeec9f40dd2012-08-15 11:35:25 -070055 LOG(WARNING) << "Null placeholder";
buzbee9a2487f2012-07-26 14:01:13 -070056 return;
57 }
buzbee2cfc6392012-05-07 14:51:40 -070058 placeholder->replaceAllUsesWith(val);
59 val->takeName(placeholder);
60 cUnit->llvmValues.elemList[sReg] = (intptr_t)val;
buzbee4be777b2012-07-12 14:38:18 -070061 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
62 DCHECK(inst != NULL);
63 inst->eraseFromParent();
buzbee2cfc6392012-05-07 14:51:40 -070064}
65
66llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
67{
68 llvm::Type* res = NULL;
69 if (loc.wide) {
70 if (loc.fp)
buzbee4f1181f2012-06-22 13:52:12 -070071 res = cUnit->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070072 else
buzbee4f1181f2012-06-22 13:52:12 -070073 res = cUnit->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070074 } else {
75 if (loc.fp) {
buzbee4f1181f2012-06-22 13:52:12 -070076 res = cUnit->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070077 } else {
78 if (loc.ref)
79 res = cUnit->irb->GetJObjectTy();
80 else
buzbee4f1181f2012-06-22 13:52:12 -070081 res = cUnit->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -070082 }
83 }
84 return res;
85}
86
buzbeead8f15e2012-06-18 14:49:45 -070087/* Create an in-memory RegLocation from an llvm Value. */
88void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
89{
90 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
91 std::string s(val->getName().str());
92 const char* valName = s.c_str();
buzbeead8f15e2012-06-18 14:49:45 -070093 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
94 DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
95 int baseSReg = INVALID_SREG;
96 int subscript = -1;
97 sscanf(valName, "v%d_%d", &baseSReg, &subscript);
98 if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
99 baseSReg = SSA_METHOD_BASEREG;
100 subscript = 0;
101 }
buzbeead8f15e2012-06-18 14:49:45 -0700102 DCHECK_NE(baseSReg, INVALID_SREG);
103 DCHECK_NE(subscript, -1);
104 // TODO: redo during C++'ification
105 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
106 INVALID_REG, INVALID_SREG, INVALID_SREG};
107 llvm::Type* ty = val->getType();
108 loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
109 (ty == cUnit->irb->getDoubleTy()));
110 loc.defined = true;
buzbeeca7a5e42012-08-20 11:12:18 -0700111 loc.home = false; // May change during promotion
buzbeead8f15e2012-06-18 14:49:45 -0700112 loc.sRegLow = baseSReg;
113 loc.origSReg = cUnit->locMap.size();
buzbeeca7a5e42012-08-20 11:12:18 -0700114 PromotionMap pMap = cUnit->promotionMap[baseSReg];
115 if (ty == cUnit->irb->getFloatTy()) {
116 loc.fp = true;
117 if (pMap.fpLocation == kLocPhysReg) {
118 loc.lowReg = pMap.fpReg;
119 loc.location = kLocPhysReg;
120 loc.home = true;
121 }
122 } else if (ty == cUnit->irb->getDoubleTy()) {
123 loc.fp = true;
124 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
125 if ((pMap.fpLocation == kLocPhysReg) &&
126 (pMapHigh.fpLocation == kLocPhysReg) &&
127 ((pMap.fpReg & 0x1) == 0) &&
128 (pMap.fpReg + 1 == pMapHigh.fpReg)) {
129 loc.lowReg = pMap.fpReg;
130 loc.highReg = pMapHigh.fpReg;
131 loc.location = kLocPhysReg;
132 loc.home = true;
133 }
134 } else if (ty == cUnit->irb->GetJObjectTy()) {
135 loc.ref = true;
136 if (pMap.coreLocation == kLocPhysReg) {
137 loc.lowReg = pMap.coreReg;
138 loc.location = kLocPhysReg;
139 loc.home = true;
140 }
141 } else if (ty == cUnit->irb->getInt64Ty()) {
142 loc.core = true;
143 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
144 if ((pMap.coreLocation == kLocPhysReg) &&
145 (pMapHigh.coreLocation == kLocPhysReg)) {
146 loc.lowReg = pMap.coreReg;
147 loc.highReg = pMapHigh.coreReg;
148 loc.location = kLocPhysReg;
149 loc.home = true;
150 }
151 } else {
152 loc.core = true;
153 if (pMap.coreLocation == kLocPhysReg) {
154 loc.lowReg = pMap.coreReg;
155 loc.location = kLocPhysReg;
156 loc.home = true;
157 }
158 }
159
160 if (cUnit->printMe && loc.home) {
161 if (loc.wide) {
buzbee0967a252012-09-14 10:43:54 -0700162 LOG(INFO) << "Promoted wide " << s << " to regs " << static_cast<int>(loc.lowReg)
buzbeeca7a5e42012-08-20 11:12:18 -0700163 << "/" << loc.highReg;
164 } else {
buzbee0967a252012-09-14 10:43:54 -0700165 LOG(INFO) << "Promoted " << s << " to reg " << static_cast<int>(loc.lowReg);
buzbeeca7a5e42012-08-20 11:12:18 -0700166 }
167 }
buzbeead8f15e2012-06-18 14:49:45 -0700168 cUnit->locMap.Put(val, loc);
169}
buzbee2cfc6392012-05-07 14:51:40 -0700170void initIR(CompilationUnit* cUnit)
171{
TDYa12755e5e6c2012-09-11 15:14:42 -0700172 QuickCompiler* quick = cUnit->quick_compiler;
buzbee692be802012-08-29 15:52:59 -0700173 cUnit->context = quick->GetLLVMContext();
174 cUnit->module = quick->GetLLVMModule();
175 cUnit->intrinsic_helper = quick->GetIntrinsicHelper();
176 cUnit->irb = quick->GetIRBuilder();
buzbee2cfc6392012-05-07 14:51:40 -0700177}
178
179const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
180 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
181}
182
buzbeef58c12c2012-07-03 15:06:29 -0700183llvm::BasicBlock* findCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
184{
185 BasicBlock* bb = oatFindBlock(cUnit, vaddr);
186 DCHECK(bb != NULL);
187 return getLLVMBlock(cUnit, bb->id);
188}
189
190void convertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
191 int32_t tableOffset, RegLocation rlSrc)
192{
193 const Instruction::PackedSwitchPayload* payload =
194 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
195 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
196
197 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
198
199 llvm::SwitchInst* sw =
200 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
201 payload->case_count);
202
203 for (uint16_t i = 0; i < payload->case_count; ++i) {
204 llvm::BasicBlock* llvmBB =
205 findCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
206 sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
207 }
208 llvm::MDNode* switchNode =
209 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
210 sw->setMetadata("SwitchTable", switchNode);
211 bb->taken = NULL;
212 bb->fallThrough = NULL;
213}
214
buzbeea1da8a52012-07-09 14:00:21 -0700215void convertSparseSwitch(CompilationUnit* cUnit, BasicBlock* bb,
216 int32_t tableOffset, RegLocation rlSrc)
217{
218 const Instruction::SparseSwitchPayload* payload =
219 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
220 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
221
222 const int32_t* keys = payload->GetKeys();
223 const int32_t* targets = payload->GetTargets();
224
225 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
226
227 llvm::SwitchInst* sw =
228 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
229 payload->case_count);
230
231 for (size_t i = 0; i < payload->case_count; ++i) {
232 llvm::BasicBlock* llvmBB =
233 findCaseTarget(cUnit, cUnit->currentDalvikOffset + targets[i]);
234 sw->addCase(cUnit->irb->getInt32(keys[i]), llvmBB);
235 }
236 llvm::MDNode* switchNode =
237 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
238 sw->setMetadata("SwitchTable", switchNode);
239 bb->taken = NULL;
240 bb->fallThrough = NULL;
241}
242
buzbee8fa0fda2012-06-27 15:44:52 -0700243void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
244 greenland::IntrinsicHelper::IntrinsicId id,
245 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700246{
buzbee8fa0fda2012-06-27 15:44:52 -0700247 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700248 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700249 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
250 defineValue(cUnit, res, rlDest.origSReg);
251}
252
253void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
254 greenland::IntrinsicHelper::IntrinsicId id,
255 RegLocation rlSrc)
256{
257 llvm::SmallVector<llvm::Value*, 2> args;
258 args.push_back(cUnit->irb->getInt32(fieldIndex));
259 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
260 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
261 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700262}
263
buzbee101305f2012-06-28 18:00:56 -0700264void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
265 RegLocation rlArray)
266{
267 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700268 id = greenland::IntrinsicHelper::HLFillArrayData;
buzbee101305f2012-06-28 18:00:56 -0700269 llvm::SmallVector<llvm::Value*, 2> args;
270 args.push_back(cUnit->irb->getInt32(offset));
271 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
272 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
273 cUnit->irb->CreateCall(intr, args);
274}
275
buzbee2cfc6392012-05-07 14:51:40 -0700276llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
277 RegLocation loc)
278{
279 greenland::IntrinsicHelper::IntrinsicId id;
280 if (loc.wide) {
281 if (loc.fp) {
282 id = greenland::IntrinsicHelper::ConstDouble;
283 } else {
284 id = greenland::IntrinsicHelper::ConstLong;
285 }
286 } else {
287 if (loc.fp) {
288 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700289 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700290 id = greenland::IntrinsicHelper::ConstObj;
291 } else {
292 id = greenland::IntrinsicHelper::ConstInt;
293 }
294 }
295 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
296 return cUnit->irb->CreateCall(intr, src);
297}
buzbeeb03f4872012-06-11 15:22:11 -0700298
299void emitPopShadowFrame(CompilationUnit* cUnit)
300{
301 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
302 greenland::IntrinsicHelper::PopShadowFrame);
303 cUnit->irb->CreateCall(intr);
304}
305
buzbee2cfc6392012-05-07 14:51:40 -0700306llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
307 RegLocation loc)
308{
309 greenland::IntrinsicHelper::IntrinsicId id;
310 if (loc.wide) {
311 if (loc.fp) {
312 id = greenland::IntrinsicHelper::CopyDouble;
313 } else {
314 id = greenland::IntrinsicHelper::CopyLong;
315 }
316 } else {
317 if (loc.fp) {
318 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700319 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700320 id = greenland::IntrinsicHelper::CopyObj;
321 } else {
322 id = greenland::IntrinsicHelper::CopyInt;
323 }
324 }
325 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
326 return cUnit->irb->CreateCall(intr, src);
327}
328
buzbee32412962012-06-26 16:27:56 -0700329void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
330{
331 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
332 greenland::IntrinsicHelper::GetException);
333 llvm::Value* res = cUnit->irb->CreateCall(func);
334 defineValue(cUnit, res, rlDest.origSReg);
335}
336
337void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
338{
339 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
340 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
TDYa127f71bf5a2012-07-29 20:09:52 -0700341 greenland::IntrinsicHelper::HLThrowException);
buzbee32412962012-06-26 16:27:56 -0700342 cUnit->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700343}
344
buzbee8fa0fda2012-06-27 15:44:52 -0700345void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
346 greenland::IntrinsicHelper::IntrinsicId id,
347 RegLocation rlSrc)
348{
349 llvm::SmallVector<llvm::Value*, 2> args;
350 args.push_back(cUnit->irb->getInt32(optFlags));
351 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
352 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
353 cUnit->irb->CreateCall(func, args);
354}
355
buzbee76592632012-06-29 15:18:35 -0700356void convertArrayLength(CompilationUnit* cUnit, int optFlags,
357 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700358{
359 llvm::SmallVector<llvm::Value*, 2> args;
360 args.push_back(cUnit->irb->getInt32(optFlags));
361 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
362 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700363 greenland::IntrinsicHelper::OptArrayLength);
buzbee76592632012-06-29 15:18:35 -0700364 llvm::Value* res = cUnit->irb->CreateCall(func, args);
365 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700366}
367
buzbee2cfc6392012-05-07 14:51:40 -0700368void emitSuspendCheck(CompilationUnit* cUnit)
369{
370 greenland::IntrinsicHelper::IntrinsicId id =
371 greenland::IntrinsicHelper::CheckSuspend;
372 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
373 cUnit->irb->CreateCall(intr);
374}
375
376llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
377 llvm::Value* src1, llvm::Value* src2)
378{
379 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700380 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700381 switch(cc) {
382 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
383 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
384 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
385 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
386 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
387 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
388 default: LOG(FATAL) << "Unexpected cc value " << cc;
389 }
390 return res;
391}
392
393void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
394 ConditionCode cc, RegLocation rlSrc1,
395 RegLocation rlSrc2)
396{
397 if (bb->taken->startOffset <= mir->offset) {
398 emitSuspendCheck(cUnit);
399 }
400 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
401 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
402 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
403 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
404 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
405 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700406 // Don't redo the fallthrough branch in the BB driver
407 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700408}
409
410void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
411 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
412{
413 if (bb->taken->startOffset <= mir->offset) {
414 emitSuspendCheck(cUnit);
415 }
416 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
417 llvm::Value* src2;
418 if (rlSrc1.ref) {
419 src2 = cUnit->irb->GetJNull();
420 } else {
421 src2 = cUnit->irb->getInt32(0);
422 }
423 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700424 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
425 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700426 // Don't redo the fallthrough branch in the BB driver
427 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700428}
429
430llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
431 llvm::Value* src1, llvm::Value* src2)
432{
433 greenland::IntrinsicHelper::IntrinsicId id;
434 if (isLong) {
435 if (isDiv) {
436 id = greenland::IntrinsicHelper::DivLong;
437 } else {
438 id = greenland::IntrinsicHelper::RemLong;
439 }
Logan Chien554e6072012-07-23 20:00:01 -0700440 } else {
441 if (isDiv) {
buzbee2cfc6392012-05-07 14:51:40 -0700442 id = greenland::IntrinsicHelper::DivInt;
443 } else {
444 id = greenland::IntrinsicHelper::RemInt;
Logan Chien554e6072012-07-23 20:00:01 -0700445 }
buzbee2cfc6392012-05-07 14:51:40 -0700446 }
447 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
448 llvm::SmallVector<llvm::Value*, 2>args;
449 args.push_back(src1);
450 args.push_back(src2);
451 return cUnit->irb->CreateCall(intr, args);
452}
453
454llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
455 llvm::Value* src1, llvm::Value* src2)
456{
457 llvm::Value* res = NULL;
458 switch(op) {
459 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
460 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700461 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700462 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
463 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
464 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
465 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
466 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
467 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700468 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
469 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
470 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700471 default:
472 LOG(FATAL) << "Invalid op " << op;
473 }
474 return res;
475}
476
477void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
478 RegLocation rlSrc1, RegLocation rlSrc2)
479{
480 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
481 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
482 llvm::Value* res = NULL;
483 switch(op) {
484 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
485 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
486 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
487 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
488 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
489 default:
490 LOG(FATAL) << "Invalid op " << op;
491 }
492 defineValue(cUnit, res, rlDest.origSReg);
493}
494
buzbee2a83e8f2012-07-13 16:42:30 -0700495void convertShift(CompilationUnit* cUnit,
496 greenland::IntrinsicHelper::IntrinsicId id,
497 RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
buzbee4f1181f2012-06-22 13:52:12 -0700498{
buzbee2a83e8f2012-07-13 16:42:30 -0700499 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
500 llvm::SmallVector<llvm::Value*, 2>args;
501 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
502 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
503 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
504 defineValue(cUnit, res, rlDest.origSReg);
505}
506
507void convertShiftLit(CompilationUnit* cUnit,
508 greenland::IntrinsicHelper::IntrinsicId id,
509 RegLocation rlDest, RegLocation rlSrc, int shiftAmount)
510{
511 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
512 llvm::SmallVector<llvm::Value*, 2>args;
513 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
514 args.push_back(cUnit->irb->getInt32(shiftAmount));
515 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700516 defineValue(cUnit, res, rlDest.origSReg);
517}
518
buzbee2cfc6392012-05-07 14:51:40 -0700519void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
520 RegLocation rlSrc1, RegLocation rlSrc2)
521{
522 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
523 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700524 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700525 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
526 defineValue(cUnit, res, rlDest.origSReg);
527}
528
buzbeeb03f4872012-06-11 15:22:11 -0700529void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
530{
531 int index = -1;
532 DCHECK(newVal != NULL);
533 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
534 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
535 if (cUnit->shadowMap[i] == vReg) {
536 index = i;
537 break;
538 }
539 }
TDYa127347166a2012-08-23 12:23:44 -0700540 if (index == -1) {
541 return;
542 }
buzbee6459e7c2012-10-02 14:42:41 -0700543 llvm::Type* ty = newVal->getType();
buzbeeb03f4872012-06-11 15:22:11 -0700544 greenland::IntrinsicHelper::IntrinsicId id =
545 greenland::IntrinsicHelper::SetShadowFrameEntry;
546 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
547 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
buzbee6459e7c2012-10-02 14:42:41 -0700548 // If newVal is a Null pointer, we'll see it here as a const int. Replace
549 if (!ty->isPointerTy()) {
550 // TODO: assert newVal created w/ dex_lang_const_int(0) or dex_lang_const_float(0)
551 newVal = cUnit->irb->GetJNull();
552 }
buzbeeb03f4872012-06-11 15:22:11 -0700553 llvm::Value* args[] = { newVal, tableSlot };
554 cUnit->irb->CreateCall(func, args);
555}
556
buzbee2cfc6392012-05-07 14:51:40 -0700557void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
558 RegLocation rlSrc1, int32_t imm)
559{
560 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
561 llvm::Value* src2 = cUnit->irb->getInt32(imm);
562 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
563 defineValue(cUnit, res, rlDest.origSReg);
564}
565
buzbee101305f2012-06-28 18:00:56 -0700566/*
567 * Process arguments for invoke. Note: this code is also used to
568 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
569 * The requirements are similar.
570 */
buzbee6969d502012-06-15 16:40:31 -0700571void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700572 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700573{
574 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
575 llvm::SmallVector<llvm::Value*, 10> args;
576 // Insert the invokeType
577 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
578 // Insert the method_idx
579 args.push_back(cUnit->irb->getInt32(info->index));
580 // Insert the optimization flags
581 args.push_back(cUnit->irb->getInt32(info->optFlags));
582 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700583 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700584 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
585 args.push_back(val);
586 i += info->args[i].wide ? 2 : 1;
587 }
588 /*
589 * Choose the invoke return type based on actual usage. Note: may
590 * be different than shorty. For example, if a function return value
591 * is not used, we'll treat this as a void invoke.
592 */
593 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700594 if (isFilledNewArray) {
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700595 id = greenland::IntrinsicHelper::HLFilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700596 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700597 id = greenland::IntrinsicHelper::HLInvokeVoid;
598 } else {
599 if (info->result.wide) {
600 if (info->result.fp) {
601 id = greenland::IntrinsicHelper::HLInvokeDouble;
602 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700603 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700604 }
605 } else if (info->result.ref) {
606 id = greenland::IntrinsicHelper::HLInvokeObj;
607 } else if (info->result.fp) {
608 id = greenland::IntrinsicHelper::HLInvokeFloat;
609 } else {
610 id = greenland::IntrinsicHelper::HLInvokeInt;
611 }
612 }
613 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
614 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
615 if (info->result.location != kLocInvalid) {
616 defineValue(cUnit, res, info->result.origSReg);
TDYa127890ea892012-08-22 10:49:42 -0700617 if (info->result.ref) {
618 setShadowFrameEntry(cUnit, (llvm::Value*)
619 cUnit->llvmValues.elemList[info->result.origSReg]);
620 }
buzbee6969d502012-06-15 16:40:31 -0700621 }
622}
623
buzbee101305f2012-06-28 18:00:56 -0700624void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
625 greenland::IntrinsicHelper::IntrinsicId id,
626 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700627{
buzbee6969d502012-06-15 16:40:31 -0700628 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700629 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700630 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
631 defineValue(cUnit, res, rlDest.origSReg);
632}
633
buzbee101305f2012-06-28 18:00:56 -0700634void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
635 RegLocation rlSrc)
636{
637 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700638 id = greenland::IntrinsicHelper::HLCheckCast;
buzbee101305f2012-06-28 18:00:56 -0700639 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
640 llvm::SmallVector<llvm::Value*, 2> args;
641 args.push_back(cUnit->irb->getInt32(type_idx));
642 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
643 cUnit->irb->CreateCall(intr, args);
644}
645
buzbee8fa0fda2012-06-27 15:44:52 -0700646void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
647 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700648{
649 greenland::IntrinsicHelper::IntrinsicId id;
650 id = greenland::IntrinsicHelper::NewInstance;
651 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
652 llvm::Value* index = cUnit->irb->getInt32(type_idx);
653 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
654 defineValue(cUnit, res, rlDest.origSReg);
655}
656
buzbee8fa0fda2012-06-27 15:44:52 -0700657void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
658 RegLocation rlDest, RegLocation rlSrc)
659{
660 greenland::IntrinsicHelper::IntrinsicId id;
661 id = greenland::IntrinsicHelper::NewArray;
662 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
663 llvm::SmallVector<llvm::Value*, 2> args;
664 args.push_back(cUnit->irb->getInt32(type_idx));
665 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
666 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
667 defineValue(cUnit, res, rlDest.origSReg);
668}
669
670void convertAget(CompilationUnit* cUnit, int optFlags,
671 greenland::IntrinsicHelper::IntrinsicId id,
672 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
673{
674 llvm::SmallVector<llvm::Value*, 3> args;
675 args.push_back(cUnit->irb->getInt32(optFlags));
676 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
677 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
678 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
679 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
680 defineValue(cUnit, res, rlDest.origSReg);
681}
682
683void convertAput(CompilationUnit* cUnit, int optFlags,
684 greenland::IntrinsicHelper::IntrinsicId id,
685 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
686{
687 llvm::SmallVector<llvm::Value*, 4> args;
688 args.push_back(cUnit->irb->getInt32(optFlags));
689 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
690 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
691 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
692 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
693 cUnit->irb->CreateCall(intr, args);
694}
695
buzbee101305f2012-06-28 18:00:56 -0700696void convertIget(CompilationUnit* cUnit, int optFlags,
697 greenland::IntrinsicHelper::IntrinsicId id,
698 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
699{
700 llvm::SmallVector<llvm::Value*, 3> args;
701 args.push_back(cUnit->irb->getInt32(optFlags));
702 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
703 args.push_back(cUnit->irb->getInt32(fieldIndex));
704 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
705 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
706 defineValue(cUnit, res, rlDest.origSReg);
707}
708
709void convertIput(CompilationUnit* cUnit, int optFlags,
710 greenland::IntrinsicHelper::IntrinsicId id,
711 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
712{
713 llvm::SmallVector<llvm::Value*, 4> args;
714 args.push_back(cUnit->irb->getInt32(optFlags));
715 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
716 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
717 args.push_back(cUnit->irb->getInt32(fieldIndex));
718 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
719 cUnit->irb->CreateCall(intr, args);
720}
721
buzbee8fa0fda2012-06-27 15:44:52 -0700722void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
723 RegLocation rlDest, RegLocation rlSrc)
724{
725 greenland::IntrinsicHelper::IntrinsicId id;
726 id = greenland::IntrinsicHelper::InstanceOf;
727 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
728 llvm::SmallVector<llvm::Value*, 2> args;
729 args.push_back(cUnit->irb->getInt32(type_idx));
730 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
731 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
732 defineValue(cUnit, res, rlDest.origSReg);
733}
734
buzbee101305f2012-06-28 18:00:56 -0700735void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
736 RegLocation rlSrc)
737{
738 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
739 cUnit->irb->getInt64Ty());
740 defineValue(cUnit, res, rlDest.origSReg);
741}
742
buzbee76592632012-06-29 15:18:35 -0700743void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
744 RegLocation rlSrc)
745{
746 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
747 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
748 defineValue(cUnit, res, rlDest.origSReg);
749}
750
751void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
752 RegLocation rlSrc)
753{
754 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
755 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
756 defineValue(cUnit, res, rlDest.origSReg);
757}
758
759void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
760 RegLocation rlSrc)
761{
762 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
763 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
764 defineValue(cUnit, res, rlDest.origSReg);
765}
766
767void convertWideComparison(CompilationUnit* cUnit,
768 greenland::IntrinsicHelper::IntrinsicId id,
769 RegLocation rlDest, RegLocation rlSrc1,
770 RegLocation rlSrc2)
771{
772 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
773 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
774 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
775 llvm::SmallVector<llvm::Value*, 2> args;
776 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
777 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
778 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
779 defineValue(cUnit, res, rlDest.origSReg);
780}
781
buzbee101305f2012-06-28 18:00:56 -0700782void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
783 RegLocation rlSrc,
784 greenland::IntrinsicHelper::IntrinsicId id)
785{
786 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700787 llvm::Value* res =
788 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
789 defineValue(cUnit, res, rlDest.origSReg);
790}
791
792void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
793 RegLocation rlSrc)
794{
795 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
796 defineValue(cUnit, res, rlDest.origSReg);
797}
798
799void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
800 RegLocation rlSrc)
801{
802 llvm::Value* res =
803 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
804 defineValue(cUnit, res, rlDest.origSReg);
805}
806
TDYa1274ec8ccd2012-08-11 07:04:57 -0700807void convertFPToInt(CompilationUnit* cUnit,
808 greenland::IntrinsicHelper::IntrinsicId id,
809 RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700810 RegLocation rlSrc)
811{
TDYa1274ec8ccd2012-08-11 07:04:57 -0700812 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
813 llvm::Value* res = cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
buzbee76592632012-06-29 15:18:35 -0700814 defineValue(cUnit, res, rlDest.origSReg);
815}
816
817
818void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
819 RegLocation rlSrc)
820{
821 llvm::Value* res =
822 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
823 defineValue(cUnit, res, rlDest.origSReg);
824}
825
826void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
827 RegLocation rlSrc)
828{
829 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
830 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700831 defineValue(cUnit, res, rlDest.origSReg);
832}
833
buzbee2cfc6392012-05-07 14:51:40 -0700834/*
835 * Target-independent code generation. Use only high-level
836 * load/store utilities here, or target-dependent genXX() handlers
837 * when necessary.
838 */
839bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
840 llvm::BasicBlock* llvmBB, LIR* labelList)
841{
842 bool res = false; // Assume success
843 RegLocation rlSrc[3];
844 RegLocation rlDest = badLoc;
buzbee2cfc6392012-05-07 14:51:40 -0700845 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee6969d502012-06-15 16:40:31 -0700846 uint32_t vB = mir->dalvikInsn.vB;
847 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700848 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700849
buzbeeb03f4872012-06-11 15:22:11 -0700850 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700851
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700852 if (cUnit->printMe) {
853 if ((int)opcode < kMirOpFirst) {
854 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x"
855 << std::hex << (int)opcode;
856 } else {
857 LOG(INFO) << ".. opcode 0x" << std::hex << (int)opcode;
858 }
859 }
860
buzbee2cfc6392012-05-07 14:51:40 -0700861 /* Prep Src and Dest locations */
862 int nextSreg = 0;
863 int nextLoc = 0;
864 int attrs = oatDataFlowAttributes[opcode];
865 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
866 if (attrs & DF_UA) {
867 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700868 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700869 nextSreg+= 2;
870 } else {
871 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
872 nextSreg++;
873 }
874 }
875 if (attrs & DF_UB) {
876 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700877 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700878 nextSreg+= 2;
879 } else {
880 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
881 nextSreg++;
882 }
883 }
884 if (attrs & DF_UC) {
885 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700886 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700887 } else {
888 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
889 }
890 }
891 if (attrs & DF_DA) {
892 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700893 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700894 } else {
buzbee15bf9802012-06-12 17:49:27 -0700895 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700896 if (rlDest.ref) {
897 objectDefinition = true;
898 }
buzbee2cfc6392012-05-07 14:51:40 -0700899 }
900 }
901
902 switch (opcode) {
903 case Instruction::NOP:
904 break;
905
906 case Instruction::MOVE:
907 case Instruction::MOVE_OBJECT:
908 case Instruction::MOVE_16:
909 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700910 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700911 case Instruction::MOVE_FROM16:
912 case Instruction::MOVE_WIDE:
913 case Instruction::MOVE_WIDE_16:
914 case Instruction::MOVE_WIDE_FROM16: {
915 /*
916 * Moves/copies are meaningless in pure SSA register form,
917 * but we need to preserve them for the conversion back into
918 * MIR (at least until we stop using the Dalvik register maps).
919 * Insert a dummy intrinsic copy call, which will be recognized
920 * by the quick path and removed by the portable path.
921 */
922 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
923 llvm::Value* res = emitCopy(cUnit, src, rlDest);
924 defineValue(cUnit, res, rlDest.origSReg);
925 }
926 break;
927
928 case Instruction::CONST:
929 case Instruction::CONST_4:
930 case Instruction::CONST_16: {
TDYa127347166a2012-08-23 12:23:44 -0700931 if (vB == 0) {
932 objectDefinition = true;
933 }
buzbee6969d502012-06-15 16:40:31 -0700934 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700935 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
936 defineValue(cUnit, res, rlDest.origSReg);
937 }
938 break;
939
940 case Instruction::CONST_WIDE_16:
941 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700942 // Sign extend to 64 bits
943 int64_t imm = static_cast<int32_t>(vB);
944 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700945 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
946 defineValue(cUnit, res, rlDest.origSReg);
947 }
948 break;
949
950 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700951 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700952 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
953 defineValue(cUnit, res, rlDest.origSReg);
954 }
955 break;
956
957 case Instruction::CONST_WIDE: {
958 llvm::Constant* immValue =
959 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
960 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
961 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700962 }
963 break;
buzbee2cfc6392012-05-07 14:51:40 -0700964 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700965 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700966 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
967 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
968 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700969 }
970 break;
971
buzbee8fa0fda2012-06-27 15:44:52 -0700972 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700973 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700974 rlSrc[0]);
975 break;
976 case Instruction::SPUT:
977 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700978 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700979 rlSrc[0]);
980 } else {
buzbee76592632012-06-29 15:18:35 -0700981 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700982 }
983 break;
984 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700985 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700986 rlSrc[0]);
987 break;
988 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700989 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700990 break;
991 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700992 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700993 break;
994 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -0700995 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700996 break;
997 case Instruction::SPUT_WIDE:
998 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700999 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -07001000 rlSrc[0]);
1001 } else {
buzbee76592632012-06-29 15:18:35 -07001002 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -07001003 rlSrc[0]);
1004 }
1005 break;
1006
1007 case Instruction::SGET_OBJECT:
1008 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
1009 break;
1010 case Instruction::SGET:
1011 if (rlDest.fp) {
1012 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
1013 } else {
1014 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
1015 }
1016 break;
1017 case Instruction::SGET_BOOLEAN:
1018 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
1019 break;
1020 case Instruction::SGET_BYTE:
1021 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
1022 break;
1023 case Instruction::SGET_CHAR:
1024 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
1025 break;
1026 case Instruction::SGET_SHORT:
1027 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
1028 break;
1029 case Instruction::SGET_WIDE:
1030 if (rlDest.fp) {
1031 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
1032 rlDest);
1033 } else {
1034 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001035 }
1036 break;
buzbee2cfc6392012-05-07 14:51:40 -07001037
1038 case Instruction::RETURN_WIDE:
1039 case Instruction::RETURN:
1040 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -07001041 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001042 emitSuspendCheck(cUnit);
1043 }
buzbeeb03f4872012-06-11 15:22:11 -07001044 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001045 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
1046 bb->hasReturn = true;
1047 }
1048 break;
1049
1050 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001051 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001052 emitSuspendCheck(cUnit);
1053 }
buzbeeb03f4872012-06-11 15:22:11 -07001054 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001055 cUnit->irb->CreateRetVoid();
1056 bb->hasReturn = true;
1057 }
1058 break;
1059
1060 case Instruction::IF_EQ:
1061 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1062 break;
1063 case Instruction::IF_NE:
1064 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1065 break;
1066 case Instruction::IF_LT:
1067 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1068 break;
1069 case Instruction::IF_GE:
1070 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1071 break;
1072 case Instruction::IF_GT:
1073 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1074 break;
1075 case Instruction::IF_LE:
1076 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1077 break;
1078 case Instruction::IF_EQZ:
1079 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1080 break;
1081 case Instruction::IF_NEZ:
1082 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1083 break;
1084 case Instruction::IF_LTZ:
1085 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1086 break;
1087 case Instruction::IF_GEZ:
1088 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1089 break;
1090 case Instruction::IF_GTZ:
1091 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1092 break;
1093 case Instruction::IF_LEZ:
1094 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1095 break;
1096
1097 case Instruction::GOTO:
1098 case Instruction::GOTO_16:
1099 case Instruction::GOTO_32: {
1100 if (bb->taken->startOffset <= bb->startOffset) {
1101 emitSuspendCheck(cUnit);
1102 }
1103 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1104 }
1105 break;
1106
1107 case Instruction::ADD_LONG:
1108 case Instruction::ADD_LONG_2ADDR:
1109 case Instruction::ADD_INT:
1110 case Instruction::ADD_INT_2ADDR:
1111 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1112 break;
1113 case Instruction::SUB_LONG:
1114 case Instruction::SUB_LONG_2ADDR:
1115 case Instruction::SUB_INT:
1116 case Instruction::SUB_INT_2ADDR:
1117 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1118 break;
1119 case Instruction::MUL_LONG:
1120 case Instruction::MUL_LONG_2ADDR:
1121 case Instruction::MUL_INT:
1122 case Instruction::MUL_INT_2ADDR:
1123 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1124 break;
1125 case Instruction::DIV_LONG:
1126 case Instruction::DIV_LONG_2ADDR:
1127 case Instruction::DIV_INT:
1128 case Instruction::DIV_INT_2ADDR:
1129 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1130 break;
1131 case Instruction::REM_LONG:
1132 case Instruction::REM_LONG_2ADDR:
1133 case Instruction::REM_INT:
1134 case Instruction::REM_INT_2ADDR:
1135 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1136 break;
1137 case Instruction::AND_LONG:
1138 case Instruction::AND_LONG_2ADDR:
1139 case Instruction::AND_INT:
1140 case Instruction::AND_INT_2ADDR:
1141 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1142 break;
1143 case Instruction::OR_LONG:
1144 case Instruction::OR_LONG_2ADDR:
1145 case Instruction::OR_INT:
1146 case Instruction::OR_INT_2ADDR:
1147 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1148 break;
1149 case Instruction::XOR_LONG:
1150 case Instruction::XOR_LONG_2ADDR:
1151 case Instruction::XOR_INT:
1152 case Instruction::XOR_INT_2ADDR:
1153 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1154 break;
1155 case Instruction::SHL_LONG:
1156 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001157 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1158 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001159 break;
buzbee2cfc6392012-05-07 14:51:40 -07001160 case Instruction::SHL_INT:
1161 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001162 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1163 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001164 break;
1165 case Instruction::SHR_LONG:
1166 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001167 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1168 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001169 break;
buzbee2cfc6392012-05-07 14:51:40 -07001170 case Instruction::SHR_INT:
1171 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001172 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1173 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001174 break;
1175 case Instruction::USHR_LONG:
1176 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001177 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1178 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001179 break;
buzbee2cfc6392012-05-07 14:51:40 -07001180 case Instruction::USHR_INT:
1181 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001182 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1183 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001184 break;
1185
1186 case Instruction::ADD_INT_LIT16:
1187 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001188 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001189 break;
1190 case Instruction::RSUB_INT:
1191 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001192 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001193 break;
1194 case Instruction::MUL_INT_LIT16:
1195 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001196 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001197 break;
1198 case Instruction::DIV_INT_LIT16:
1199 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001200 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001201 break;
1202 case Instruction::REM_INT_LIT16:
1203 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001204 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001205 break;
1206 case Instruction::AND_INT_LIT16:
1207 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001208 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001209 break;
1210 case Instruction::OR_INT_LIT16:
1211 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001212 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001213 break;
1214 case Instruction::XOR_INT_LIT16:
1215 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001216 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001217 break;
1218 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001219 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1220 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001221 break;
1222 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001223 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1224 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001225 break;
1226 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001227 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1228 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001229 break;
1230
1231 case Instruction::ADD_FLOAT:
1232 case Instruction::ADD_FLOAT_2ADDR:
1233 case Instruction::ADD_DOUBLE:
1234 case Instruction::ADD_DOUBLE_2ADDR:
1235 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1236 break;
1237
1238 case Instruction::SUB_FLOAT:
1239 case Instruction::SUB_FLOAT_2ADDR:
1240 case Instruction::SUB_DOUBLE:
1241 case Instruction::SUB_DOUBLE_2ADDR:
1242 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1243 break;
1244
1245 case Instruction::MUL_FLOAT:
1246 case Instruction::MUL_FLOAT_2ADDR:
1247 case Instruction::MUL_DOUBLE:
1248 case Instruction::MUL_DOUBLE_2ADDR:
1249 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1250 break;
1251
1252 case Instruction::DIV_FLOAT:
1253 case Instruction::DIV_FLOAT_2ADDR:
1254 case Instruction::DIV_DOUBLE:
1255 case Instruction::DIV_DOUBLE_2ADDR:
1256 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1257 break;
1258
1259 case Instruction::REM_FLOAT:
1260 case Instruction::REM_FLOAT_2ADDR:
1261 case Instruction::REM_DOUBLE:
1262 case Instruction::REM_DOUBLE_2ADDR:
1263 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1264 break;
1265
buzbee6969d502012-06-15 16:40:31 -07001266 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001267 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1268 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001269 break;
1270 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001271 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1272 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001273 break;
1274
1275 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001276 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1277 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001278 break;
1279 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001280 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1281 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001282 break;
1283
1284 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001285 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1286 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001287 break;
1288 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001289 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1290 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001291 break;
1292
1293 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001294 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1295 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001296 break;
1297 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001298 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1299 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001300 break;
1301
1302 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001303 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1304 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001305 break;
1306 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001307 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1308 false /* NewFilledArray */);
1309 break;
1310 case Instruction::FILLED_NEW_ARRAY:
1311 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1312 true /* NewFilledArray */);
1313 break;
1314 case Instruction::FILLED_NEW_ARRAY_RANGE:
1315 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1316 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001317 break;
1318
1319 case Instruction::CONST_STRING:
1320 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001321 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1322 rlDest);
1323 break;
1324
1325 case Instruction::CONST_CLASS:
1326 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1327 rlDest);
1328 break;
1329
1330 case Instruction::CHECK_CAST:
1331 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001332 break;
1333
buzbee4f1181f2012-06-22 13:52:12 -07001334 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001335 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001336 break;
1337
buzbee32412962012-06-26 16:27:56 -07001338 case Instruction::MOVE_EXCEPTION:
1339 convertMoveException(cUnit, rlDest);
1340 break;
1341
1342 case Instruction::THROW:
1343 convertThrow(cUnit, rlSrc[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001344 /*
1345 * If this throw is standalone, terminate.
1346 * If it might rethrow, force termination
1347 * of the following block.
1348 */
1349 if (bb->fallThrough == NULL) {
1350 cUnit->irb->CreateUnreachable();
1351 } else {
1352 bb->fallThrough->fallThrough = NULL;
1353 bb->fallThrough->taken = NULL;
1354 }
buzbee32412962012-06-26 16:27:56 -07001355 break;
1356
buzbee2cfc6392012-05-07 14:51:40 -07001357 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001358 case Instruction::MOVE_RESULT:
1359 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001360 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001361 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001362 */
jeffhao9a4f0032012-08-30 16:17:40 -07001363 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001364 break;
1365
1366 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001367 convertMonitorEnterExit(cUnit, optFlags,
1368 greenland::IntrinsicHelper::MonitorEnter,
1369 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001370 break;
1371
1372 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001373 convertMonitorEnterExit(cUnit, optFlags,
1374 greenland::IntrinsicHelper::MonitorExit,
1375 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001376 break;
1377
1378 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001379 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001380 break;
1381
1382 case Instruction::NEW_ARRAY:
1383 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1384 break;
1385
1386 case Instruction::INSTANCE_OF:
1387 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1388 break;
1389
1390 case Instruction::AGET:
1391 if (rlDest.fp) {
1392 convertAget(cUnit, optFlags,
1393 greenland::IntrinsicHelper::HLArrayGetFloat,
1394 rlDest, rlSrc[0], rlSrc[1]);
1395 } else {
1396 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1397 rlDest, rlSrc[0], rlSrc[1]);
1398 }
1399 break;
1400 case Instruction::AGET_OBJECT:
1401 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1402 rlDest, rlSrc[0], rlSrc[1]);
1403 break;
1404 case Instruction::AGET_BOOLEAN:
1405 convertAget(cUnit, optFlags,
1406 greenland::IntrinsicHelper::HLArrayGetBoolean,
1407 rlDest, rlSrc[0], rlSrc[1]);
1408 break;
1409 case Instruction::AGET_BYTE:
1410 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1411 rlDest, rlSrc[0], rlSrc[1]);
1412 break;
1413 case Instruction::AGET_CHAR:
1414 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1415 rlDest, rlSrc[0], rlSrc[1]);
1416 break;
1417 case Instruction::AGET_SHORT:
1418 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1419 rlDest, rlSrc[0], rlSrc[1]);
1420 break;
1421 case Instruction::AGET_WIDE:
1422 if (rlDest.fp) {
1423 convertAget(cUnit, optFlags,
1424 greenland::IntrinsicHelper::HLArrayGetDouble,
1425 rlDest, rlSrc[0], rlSrc[1]);
1426 } else {
1427 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1428 rlDest, rlSrc[0], rlSrc[1]);
1429 }
1430 break;
1431
1432 case Instruction::APUT:
1433 if (rlSrc[0].fp) {
1434 convertAput(cUnit, optFlags,
1435 greenland::IntrinsicHelper::HLArrayPutFloat,
1436 rlSrc[0], rlSrc[1], rlSrc[2]);
1437 } else {
1438 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1439 rlSrc[0], rlSrc[1], rlSrc[2]);
1440 }
1441 break;
1442 case Instruction::APUT_OBJECT:
1443 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1444 rlSrc[0], rlSrc[1], rlSrc[2]);
1445 break;
1446 case Instruction::APUT_BOOLEAN:
1447 convertAput(cUnit, optFlags,
1448 greenland::IntrinsicHelper::HLArrayPutBoolean,
1449 rlSrc[0], rlSrc[1], rlSrc[2]);
1450 break;
1451 case Instruction::APUT_BYTE:
1452 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1453 rlSrc[0], rlSrc[1], rlSrc[2]);
1454 break;
1455 case Instruction::APUT_CHAR:
1456 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1457 rlSrc[0], rlSrc[1], rlSrc[2]);
1458 break;
1459 case Instruction::APUT_SHORT:
1460 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1461 rlSrc[0], rlSrc[1], rlSrc[2]);
1462 break;
1463 case Instruction::APUT_WIDE:
1464 if (rlSrc[0].fp) {
1465 convertAput(cUnit, optFlags,
1466 greenland::IntrinsicHelper::HLArrayPutDouble,
1467 rlSrc[0], rlSrc[1], rlSrc[2]);
1468 } else {
1469 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1470 rlSrc[0], rlSrc[1], rlSrc[2]);
1471 }
1472 break;
1473
buzbee101305f2012-06-28 18:00:56 -07001474 case Instruction::IGET:
1475 if (rlDest.fp) {
1476 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001477 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001478 } else {
1479 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001480 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001481 }
buzbee2cfc6392012-05-07 14:51:40 -07001482 break;
buzbee101305f2012-06-28 18:00:56 -07001483 case Instruction::IGET_OBJECT:
1484 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001485 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001486 break;
1487 case Instruction::IGET_BOOLEAN:
1488 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001489 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001490 break;
1491 case Instruction::IGET_BYTE:
1492 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001493 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001494 break;
1495 case Instruction::IGET_CHAR:
1496 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001497 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001498 break;
1499 case Instruction::IGET_SHORT:
1500 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001501 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001502 break;
1503 case Instruction::IGET_WIDE:
1504 if (rlDest.fp) {
1505 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001506 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001507 } else {
1508 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001509 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001510 }
1511 break;
1512 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001513 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001514 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1515 rlSrc[0], rlSrc[1], vC);
1516 } else {
1517 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1518 rlSrc[0], rlSrc[1], vC);
1519 }
1520 break;
1521 case Instruction::IPUT_OBJECT:
1522 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1523 rlSrc[0], rlSrc[1], vC);
1524 break;
1525 case Instruction::IPUT_BOOLEAN:
1526 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1527 rlSrc[0], rlSrc[1], vC);
1528 break;
1529 case Instruction::IPUT_BYTE:
1530 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1531 rlSrc[0], rlSrc[1], vC);
1532 break;
1533 case Instruction::IPUT_CHAR:
1534 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1535 rlSrc[0], rlSrc[1], vC);
1536 break;
1537 case Instruction::IPUT_SHORT:
1538 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1539 rlSrc[0], rlSrc[1], vC);
1540 break;
1541 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001542 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001543 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1544 rlSrc[0], rlSrc[1], vC);
1545 } else {
1546 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1547 rlSrc[0], rlSrc[1], vC);
1548 }
buzbee2cfc6392012-05-07 14:51:40 -07001549 break;
1550
1551 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001552 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001553 break;
1554
buzbee76592632012-06-29 15:18:35 -07001555 case Instruction::LONG_TO_INT:
1556 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1557 break;
1558
buzbee101305f2012-06-28 18:00:56 -07001559 case Instruction::INT_TO_LONG:
1560 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001561 break;
1562
buzbee101305f2012-06-28 18:00:56 -07001563 case Instruction::INT_TO_CHAR:
1564 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1565 greenland::IntrinsicHelper::IntToChar);
1566 break;
1567 case Instruction::INT_TO_BYTE:
1568 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1569 greenland::IntrinsicHelper::IntToByte);
1570 break;
1571 case Instruction::INT_TO_SHORT:
1572 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1573 greenland::IntrinsicHelper::IntToShort);
1574 break;
1575
buzbee76592632012-06-29 15:18:35 -07001576 case Instruction::INT_TO_FLOAT:
1577 case Instruction::LONG_TO_FLOAT:
1578 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001579 break;
1580
buzbee76592632012-06-29 15:18:35 -07001581 case Instruction::INT_TO_DOUBLE:
1582 case Instruction::LONG_TO_DOUBLE:
1583 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001584 break;
1585
buzbee76592632012-06-29 15:18:35 -07001586 case Instruction::FLOAT_TO_DOUBLE:
1587 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001588 break;
1589
buzbee76592632012-06-29 15:18:35 -07001590 case Instruction::DOUBLE_TO_FLOAT:
1591 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001592 break;
1593
1594 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001595 case Instruction::NEG_INT:
1596 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001597 break;
1598
1599 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001600 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001601 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001602 break;
1603
buzbee76592632012-06-29 15:18:35 -07001604 case Instruction::NOT_LONG:
1605 case Instruction::NOT_INT:
1606 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001607 break;
1608
buzbee2cfc6392012-05-07 14:51:40 -07001609 case Instruction::FLOAT_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001610 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2I, rlDest, rlSrc[0]);
1611 break;
1612
buzbee2cfc6392012-05-07 14:51:40 -07001613 case Instruction::DOUBLE_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001614 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2I, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001615 break;
1616
buzbee76592632012-06-29 15:18:35 -07001617 case Instruction::FLOAT_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001618 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2L, rlDest, rlSrc[0]);
1619 break;
1620
buzbee76592632012-06-29 15:18:35 -07001621 case Instruction::DOUBLE_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001622 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2L, rlDest, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001623 break;
1624
1625 case Instruction::CMPL_FLOAT:
1626 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1627 rlDest, rlSrc[0], rlSrc[1]);
1628 break;
1629 case Instruction::CMPG_FLOAT:
1630 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1631 rlDest, rlSrc[0], rlSrc[1]);
1632 break;
1633 case Instruction::CMPL_DOUBLE:
1634 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1635 rlDest, rlSrc[0], rlSrc[1]);
1636 break;
1637 case Instruction::CMPG_DOUBLE:
1638 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1639 rlDest, rlSrc[0], rlSrc[1]);
1640 break;
1641 case Instruction::CMP_LONG:
1642 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1643 rlDest, rlSrc[0], rlSrc[1]);
1644 break;
1645
buzbee76592632012-06-29 15:18:35 -07001646 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001647 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001648 break;
1649
1650 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001651 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001652 break;
buzbee2cfc6392012-05-07 14:51:40 -07001653
1654 default:
buzbee32412962012-06-26 16:27:56 -07001655 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001656 res = true;
1657 }
buzbeeb03f4872012-06-11 15:22:11 -07001658 if (objectDefinition) {
1659 setShadowFrameEntry(cUnit, (llvm::Value*)
1660 cUnit->llvmValues.elemList[rlDest.origSReg]);
1661 }
buzbee2cfc6392012-05-07 14:51:40 -07001662 return res;
1663}
1664
1665/* Extended MIR instructions like PHI */
1666void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1667 llvm::BasicBlock* llvmBB)
1668{
1669
1670 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1671 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001672 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001673 /*
1674 * The Art compiler's Phi nodes only handle 32-bit operands,
1675 * representing wide values using a matched set of Phi nodes
1676 * for the lower and upper halves. In the llvm world, we only
1677 * want a single Phi for wides. Here we will simply discard
1678 * the Phi node representing the high word.
1679 */
1680 if (rlDest.highWord) {
1681 return; // No Phi node - handled via low word
1682 }
1683 int* incoming = (int*)mir->dalvikInsn.vB;
buzbee2cfc6392012-05-07 14:51:40 -07001684 llvm::Type* phiType =
1685 llvmTypeFromLocRec(cUnit, rlDest);
1686 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1687 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1688 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001689 // Don't check width here.
1690 loc = oatGetRawSrc(cUnit, mir, i);
1691 DCHECK_EQ(rlDest.wide, loc.wide);
1692 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1693 DCHECK_EQ(rlDest.fp, loc.fp);
1694 DCHECK_EQ(rlDest.core, loc.core);
1695 DCHECK_EQ(rlDest.ref, loc.ref);
buzbeed1643e42012-09-05 14:06:51 -07001696 SafeMap<unsigned int, unsigned int>::iterator it;
1697 it = cUnit->blockIdMap.find(incoming[i]);
1698 DCHECK(it != cUnit->blockIdMap.end());
buzbee2cfc6392012-05-07 14:51:40 -07001699 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
buzbeed1643e42012-09-05 14:06:51 -07001700 getLLVMBlock(cUnit, it->second));
buzbee2cfc6392012-05-07 14:51:40 -07001701 }
1702 defineValue(cUnit, phi, rlDest.origSReg);
1703 break;
1704 }
1705 case kMirOpCopy: {
1706 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1707 break;
1708 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001709 case kMirOpNop:
1710 if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
1711 (bb->fallThrough == NULL)) {
1712 cUnit->irb->CreateUnreachable();
1713 }
1714 break;
1715
buzbee2cfc6392012-05-07 14:51:40 -07001716#if defined(TARGET_ARM)
1717 case kMirOpFusedCmplFloat:
1718 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1719 break;
1720 case kMirOpFusedCmpgFloat:
1721 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1722 break;
1723 case kMirOpFusedCmplDouble:
1724 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1725 break;
1726 case kMirOpFusedCmpgDouble:
1727 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1728 break;
1729 case kMirOpFusedCmpLong:
1730 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1731 break;
1732#endif
1733 default:
1734 break;
1735 }
1736}
1737
1738void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1739{
1740 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001741 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001742 arrayRef.push_back(cUnit->irb->getInt32(offset));
1743 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1744 cUnit->irb->SetDexOffset(node);
1745}
1746
1747// Attach method info as metadata to special intrinsic
1748void setMethodInfo(CompilationUnit* cUnit)
1749{
1750 // We don't want dex offset on this
1751 cUnit->irb->SetDexOffset(NULL);
1752 greenland::IntrinsicHelper::IntrinsicId id;
1753 id = greenland::IntrinsicHelper::MethodInfo;
1754 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1755 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1756 llvm::SmallVector<llvm::Value*, 2> regInfo;
1757 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1758 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1759 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1760 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1761 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1762 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1763 inst->setMetadata("RegInfo", regInfoNode);
1764 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1765 llvm::SmallVector<llvm::Value*, 50> pmap;
1766 for (int i = 0; i < promoSize; i++) {
1767 PromotionMap* p = &cUnit->promotionMap[i];
1768 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1769 ((p->fpReg & 0xff) << 16) |
1770 ((p->coreReg & 0xff) << 8) |
1771 ((p->fpLocation & 0xf) << 4) |
1772 (p->coreLocation & 0xf);
1773 pmap.push_back(cUnit->irb->getInt32(mapData));
1774 }
1775 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1776 inst->setMetadata("PromotionMap", mapNode);
1777 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1778}
1779
1780/* Handle the content in each basic block */
1781bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1782{
buzbeed1643e42012-09-05 14:06:51 -07001783 if (bb->blockType == kDead) return false;
buzbee2cfc6392012-05-07 14:51:40 -07001784 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
buzbeef5f5a122012-09-21 13:57:36 -07001785 if (llvmBB == NULL) {
1786 CHECK(bb->blockType == kExitBlock);
1787 } else {
1788 cUnit->irb->SetInsertPoint(llvmBB);
1789 setDexOffset(cUnit, bb->startOffset);
1790 }
buzbee2cfc6392012-05-07 14:51:40 -07001791
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001792 if (cUnit->printMe) {
1793 LOG(INFO) << "................................";
1794 LOG(INFO) << "Block id " << bb->id;
1795 if (llvmBB != NULL) {
1796 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1797 } else {
1798 LOG(INFO) << "llvmBB is NULL";
1799 }
1800 }
1801
buzbee2cfc6392012-05-07 14:51:40 -07001802 if (bb->blockType == kEntryBlock) {
1803 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001804 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1805 cUnit->numDalvikRegisters, true,
1806 kAllocMisc);
1807 for (int i = 0; i < cUnit->numSSARegs; i++) {
buzbee6ec5e232012-09-20 15:50:03 -07001808 int vReg = SRegToVReg(cUnit, i);
1809 if (vReg > SSA_METHOD_BASEREG) {
1810 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1811 }
buzbeeb03f4872012-06-11 15:22:11 -07001812 }
1813 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1814 if (canBeRef[i]) {
1815 cUnit->numShadowFrameEntries++;
1816 }
1817 }
1818 if (cUnit->numShadowFrameEntries > 0) {
1819 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1820 cUnit->numShadowFrameEntries, true,
1821 kAllocMisc);
1822 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1823 if (canBeRef[i]) {
1824 cUnit->shadowMap[j++] = i;
1825 }
1826 }
buzbeeb03f4872012-06-11 15:22:11 -07001827 }
Shih-wei Liao569daf12012-08-10 23:22:33 -07001828 greenland::IntrinsicHelper::IntrinsicId id =
1829 greenland::IntrinsicHelper::AllocaShadowFrame;
1830 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1831 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1832 cUnit->irb->CreateCall(func, entries);
buzbee2cfc6392012-05-07 14:51:40 -07001833 } else if (bb->blockType == kExitBlock) {
1834 /*
1835 * Because of the differences between how MIR/LIR and llvm handle exit
1836 * blocks, we won't explicitly covert them. On the llvm-to-lir
1837 * path, it will need to be regenereated.
1838 */
1839 return false;
buzbee6969d502012-06-15 16:40:31 -07001840 } else if (bb->blockType == kExceptionHandling) {
1841 /*
1842 * Because we're deferring null checking, delete the associated empty
1843 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001844 */
1845 llvmBB->eraseFromParent();
1846 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001847 }
1848
1849 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1850
1851 setDexOffset(cUnit, mir->offset);
1852
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001853 int opcode = mir->dalvikInsn.opcode;
1854 Instruction::Format dalvikFormat =
1855 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001856
1857 /* If we're compiling for the debugger, generate an update callout */
1858 if (cUnit->genDebugger) {
1859 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1860 //genDebuggerUpdate(cUnit, mir->offset);
1861 }
1862
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001863 if (opcode == kMirOpCheck) {
1864 // Combine check and work halves of throwing instruction.
1865 MIR* workHalf = mir->meta.throwInsn;
1866 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
1867 opcode = mir->dalvikInsn.opcode;
1868 SSARepresentation* ssaRep = workHalf->ssaRep;
1869 workHalf->ssaRep = mir->ssaRep;
1870 mir->ssaRep = ssaRep;
1871 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1872 if (bb->successorBlockList.blockListType == kCatch) {
1873 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
1874 greenland::IntrinsicHelper::CatchTargets);
1875 llvm::Value* switchKey =
1876 cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
1877 GrowableListIterator iter;
1878 oatGrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
1879 // New basic block to use for work half
1880 llvm::BasicBlock* workBB =
1881 llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
1882 llvm::SwitchInst* sw =
1883 cUnit->irb->CreateSwitch(switchKey, workBB,
1884 bb->successorBlockList.blocks.numUsed);
1885 while (true) {
1886 SuccessorBlockInfo *successorBlockInfo =
1887 (SuccessorBlockInfo *) oatGrowableListIteratorNext(&iter);
1888 if (successorBlockInfo == NULL) break;
1889 llvm::BasicBlock *target =
1890 getLLVMBlock(cUnit, successorBlockInfo->block->id);
1891 int typeIndex = successorBlockInfo->key;
1892 sw->addCase(cUnit->irb->getInt32(typeIndex), target);
1893 }
1894 llvmBB = workBB;
1895 cUnit->irb->SetInsertPoint(llvmBB);
1896 }
1897 }
1898
1899 if (opcode >= kMirOpFirst) {
buzbee2cfc6392012-05-07 14:51:40 -07001900 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1901 continue;
1902 }
1903
1904 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1905 NULL /* labelList */);
1906 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001907 Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001908 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001909 mir->offset, opcode,
buzbee2cfc6392012-05-07 14:51:40 -07001910 Instruction::Name(dalvikOpcode),
1911 dalvikFormat);
1912 }
1913 }
1914
buzbee4be777b2012-07-12 14:38:18 -07001915 if (bb->blockType == kEntryBlock) {
1916 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1917 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001918 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1919 }
1920
1921 return false;
1922}
1923
buzbee4f4dfc72012-07-02 14:54:44 -07001924char remapShorty(char shortyType) {
1925 /*
1926 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1927 * and longs/doubles are represented as a pair of registers. When sub-word
1928 * arguments (and method results) are passed, they are extended to Dalvik
1929 * virtual register containers. Because llvm is picky about type consistency,
1930 * we must either cast the "real" type to 32-bit container multiple Dalvik
1931 * register types, or always use the expanded values.
1932 * Here, we're doing the latter. We map the shorty signature to container
1933 * types (which is valid so long as we always do a real expansion of passed
1934 * arguments and field loads).
1935 */
1936 switch(shortyType) {
1937 case 'Z' : shortyType = 'I'; break;
1938 case 'B' : shortyType = 'I'; break;
1939 case 'S' : shortyType = 'I'; break;
1940 case 'C' : shortyType = 'I'; break;
1941 default: break;
1942 }
1943 return shortyType;
1944}
1945
buzbee2cfc6392012-05-07 14:51:40 -07001946llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1947
1948 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001949 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001950 greenland::kAccurate);
1951
1952 // Get argument type
1953 std::vector<llvm::Type*> args_type;
1954
1955 // method object
1956 args_type.push_back(cUnit->irb->GetJMethodTy());
1957
1958 // Do we have a "this"?
1959 if ((cUnit->access_flags & kAccStatic) == 0) {
1960 args_type.push_back(cUnit->irb->GetJObjectTy());
1961 }
1962
1963 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001964 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001965 greenland::kAccurate));
1966 }
1967
1968 return llvm::FunctionType::get(ret_type, args_type, false);
1969}
1970
1971bool createFunction(CompilationUnit* cUnit) {
1972 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1973 /* with_signature */ false));
1974 llvm::FunctionType* func_type = getFunctionType(cUnit);
1975
1976 if (func_type == NULL) {
1977 return false;
1978 }
1979
1980 cUnit->func = llvm::Function::Create(func_type,
1981 llvm::Function::ExternalLinkage,
1982 func_name, cUnit->module);
1983
1984 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1985 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1986
1987 arg_iter->setName("method");
1988 ++arg_iter;
1989
1990 int startSReg = cUnit->numRegs;
1991
1992 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1993 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1994 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1995 }
1996
1997 return true;
1998}
1999
2000bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
2001{
2002 // Skip the exit block
buzbeed1643e42012-09-05 14:06:51 -07002003 if ((bb->blockType == kDead) ||(bb->blockType == kExitBlock)) {
buzbee2cfc6392012-05-07 14:51:40 -07002004 cUnit->idToBlockMap.Put(bb->id, NULL);
2005 } else {
2006 int offset = bb->startOffset;
2007 bool entryBlock = (bb->blockType == kEntryBlock);
2008 llvm::BasicBlock* llvmBB =
2009 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
buzbee8320f382012-09-11 16:29:42 -07002010 StringPrintf(kLabelFormat, bb->catchEntry ? kCatchBlock :
2011 kNormalBlock, offset, bb->id), cUnit->func);
buzbee2cfc6392012-05-07 14:51:40 -07002012 if (entryBlock) {
2013 cUnit->entryBB = llvmBB;
2014 cUnit->placeholderBB =
2015 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
2016 cUnit->func);
2017 }
2018 cUnit->idToBlockMap.Put(bb->id, llvmBB);
2019 }
2020 return false;
2021}
2022
2023
2024/*
2025 * Convert MIR to LLVM_IR
2026 * o For each ssa name, create LLVM named value. Type these
2027 * appropriately, and ignore high half of wide and double operands.
2028 * o For each MIR basic block, create an LLVM basic block.
2029 * o Iterate through the MIR a basic block at a time, setting arguments
2030 * to recovered ssa name.
2031 */
2032void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
2033{
2034 initIR(cUnit);
2035 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
2036
2037 // Create the function
2038 createFunction(cUnit);
2039
2040 // Create an LLVM basic block for each MIR block in dfs preorder
2041 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
2042 kPreOrderDFSTraversal, false /* isIterative */);
2043 /*
2044 * Create an llvm named value for each MIR SSA name. Note: we'll use
2045 * placeholders for all non-argument values (because we haven't seen
2046 * the definition yet).
2047 */
2048 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2049 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2050 arg_iter++; /* Skip path method */
2051 for (int i = 0; i < cUnit->numSSARegs; i++) {
2052 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07002053 RegLocation rlTemp = cUnit->regLocation[i];
2054 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07002055 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
2056 } else if ((i < cUnit->numRegs) ||
2057 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07002058 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
2059 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07002060 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
2061 val->setName(llvmSSAName(cUnit, i));
buzbee2cfc6392012-05-07 14:51:40 -07002062 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
buzbee2cfc6392012-05-07 14:51:40 -07002063 } else {
2064 // Recover previously-created argument values
2065 llvm::Value* argVal = arg_iter++;
2066 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
2067 }
2068 }
buzbee2cfc6392012-05-07 14:51:40 -07002069
2070 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
2071 kPreOrderDFSTraversal, false /* Iterative */);
2072
buzbee4be777b2012-07-12 14:38:18 -07002073 /*
2074 * In a few rare cases of verification failure, the verifier will
2075 * replace one or more Dalvik opcodes with the special
2076 * throw-verification-failure opcode. This can leave the SSA graph
2077 * in an invalid state, as definitions may be lost, while uses retained.
2078 * To work around this problem, we insert placeholder definitions for
2079 * all Dalvik SSA regs in the "placeholder" block. Here, after
2080 * bitcode conversion is complete, we examine those placeholder definitions
2081 * and delete any with no references (which normally is all of them).
2082 *
2083 * If any definitions remain, we link the placeholder block into the
2084 * CFG. Otherwise, it is deleted.
2085 */
2086 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
2087 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
2088 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2089 DCHECK(inst != NULL);
2090 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2091 DCHECK(val != NULL);
2092 if (val->getNumUses() == 0) {
2093 inst->eraseFromParent();
2094 }
2095 }
2096 setDexOffset(cUnit, 0);
2097 if (cUnit->placeholderBB->empty()) {
2098 cUnit->placeholderBB->eraseFromParent();
2099 } else {
2100 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2101 cUnit->irb->CreateBr(cUnit->entryTargetBB);
2102 cUnit->entryTargetBB = cUnit->placeholderBB;
2103 }
2104 cUnit->irb->SetInsertPoint(cUnit->entryBB);
2105 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07002106
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002107 if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
2108 if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
2109 LOG(INFO) << "Bitcode verification FAILED for "
2110 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
2111 << " of size " << cUnit->insnsSize;
2112 cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
2113 }
2114 }
buzbee2cfc6392012-05-07 14:51:40 -07002115
buzbeead8f15e2012-06-18 14:49:45 -07002116 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
2117 // Write bitcode to file
2118 std::string errmsg;
2119 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
2120 oatReplaceSpecialChars(fname);
buzbee6459e7c2012-10-02 14:42:41 -07002121 // TODO: make configurable change naming mechanism to avoid fname length issues.
buzbee4f1181f2012-06-22 13:52:12 -07002122 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002123
buzbee6459e7c2012-10-02 14:42:41 -07002124 if (fname.size() > 240) {
2125 LOG(INFO) << "Warning: bitcode filename too long. Truncated.";
2126 fname.resize(240);
2127 }
2128
buzbeead8f15e2012-06-18 14:49:45 -07002129 llvm::OwningPtr<llvm::tool_output_file> out_file(
2130 new llvm::tool_output_file(fname.c_str(), errmsg,
2131 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002132
buzbeead8f15e2012-06-18 14:49:45 -07002133 if (!errmsg.empty()) {
2134 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2135 }
2136
2137 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2138 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002139 }
buzbee2cfc6392012-05-07 14:51:40 -07002140}
2141
2142RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2143 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002144 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002145 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2146 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002147 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002148 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002149 // FIXME: need to be more robust, handle FP and be in a position to
2150 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002151 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2152 memset(&res, 0, sizeof(res));
2153 res.location = kLocPhysReg;
2154 res.lowReg = oatAllocTemp(cUnit);
2155 res.home = true;
2156 res.sRegLow = INVALID_SREG;
2157 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002158 llvm::Type* ty = val->getType();
2159 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2160 (ty == cUnit->irb->getDoubleTy()));
2161 if (res.wide) {
2162 res.highReg = oatAllocTemp(cUnit);
2163 }
buzbee4f1181f2012-06-22 13:52:12 -07002164 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002165 } else {
2166 DCHECK_EQ(valName[0], 'v');
2167 int baseSReg = INVALID_SREG;
2168 sscanf(valName.c_str(), "v%d_", &baseSReg);
2169 res = cUnit->regLocation[baseSReg];
2170 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002171 }
2172 } else {
2173 res = it->second;
2174 }
2175 return res;
2176}
2177
2178Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2179{
2180 Instruction::Code res = Instruction::NOP;
2181 if (isWide) {
2182 switch(op) {
2183 case kOpAdd: res = Instruction::ADD_LONG; break;
2184 case kOpSub: res = Instruction::SUB_LONG; break;
2185 case kOpMul: res = Instruction::MUL_LONG; break;
2186 case kOpDiv: res = Instruction::DIV_LONG; break;
2187 case kOpRem: res = Instruction::REM_LONG; break;
2188 case kOpAnd: res = Instruction::AND_LONG; break;
2189 case kOpOr: res = Instruction::OR_LONG; break;
2190 case kOpXor: res = Instruction::XOR_LONG; break;
2191 case kOpLsl: res = Instruction::SHL_LONG; break;
2192 case kOpLsr: res = Instruction::USHR_LONG; break;
2193 case kOpAsr: res = Instruction::SHR_LONG; break;
2194 default: LOG(FATAL) << "Unexpected OpKind " << op;
2195 }
2196 } else if (isConst){
2197 switch(op) {
2198 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2199 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2200 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2201 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2202 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2203 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2204 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2205 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2206 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2207 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2208 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2209 default: LOG(FATAL) << "Unexpected OpKind " << op;
2210 }
2211 } else {
2212 switch(op) {
2213 case kOpAdd: res = Instruction::ADD_INT; break;
2214 case kOpSub: res = Instruction::SUB_INT; break;
2215 case kOpMul: res = Instruction::MUL_INT; break;
2216 case kOpDiv: res = Instruction::DIV_INT; break;
2217 case kOpRem: res = Instruction::REM_INT; break;
2218 case kOpAnd: res = Instruction::AND_INT; break;
2219 case kOpOr: res = Instruction::OR_INT; break;
2220 case kOpXor: res = Instruction::XOR_INT; break;
2221 case kOpLsl: res = Instruction::SHL_INT; break;
2222 case kOpLsr: res = Instruction::USHR_INT; break;
2223 case kOpAsr: res = Instruction::SHR_INT; break;
2224 default: LOG(FATAL) << "Unexpected OpKind " << op;
2225 }
2226 }
2227 return res;
2228}
2229
buzbee4f1181f2012-06-22 13:52:12 -07002230Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2231{
2232 Instruction::Code res = Instruction::NOP;
2233 if (isWide) {
2234 switch(op) {
2235 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2236 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2237 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2238 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2239 case kOpRem: res = Instruction::REM_DOUBLE; break;
2240 default: LOG(FATAL) << "Unexpected OpKind " << op;
2241 }
2242 } else {
2243 switch(op) {
2244 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2245 case kOpSub: res = Instruction::SUB_FLOAT; break;
2246 case kOpMul: res = Instruction::MUL_FLOAT; break;
2247 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2248 case kOpRem: res = Instruction::REM_FLOAT; break;
2249 default: LOG(FATAL) << "Unexpected OpKind " << op;
2250 }
2251 }
2252 return res;
2253}
2254
2255void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2256{
2257 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002258 /*
2259 * Normally, we won't ever generate an FP operation with an immediate
2260 * operand (not supported in Dex instruction set). However, the IR builder
2261 * may insert them - in particular for createNegFP. Recognize this case
2262 * and deal with it.
2263 */
2264 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2265 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2266 DCHECK(op2C == NULL);
2267 if ((op1C != NULL) && (op == kOpSub)) {
2268 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2269 if (rlDest.wide) {
2270 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2271 } else {
2272 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2273 }
buzbee4f1181f2012-06-22 13:52:12 -07002274 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002275 DCHECK(op1C == NULL);
2276 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2277 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2278 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2279 if (rlDest.wide) {
2280 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2281 } else {
2282 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2283 }
buzbee4f1181f2012-06-22 13:52:12 -07002284 }
2285}
2286
buzbee101305f2012-06-28 18:00:56 -07002287void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2288 Instruction::Code opcode)
2289{
2290 RegLocation rlDest = getLoc(cUnit, inst);
2291 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2292 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2293}
2294
buzbee76592632012-06-29 15:18:35 -07002295void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2296{
2297 RegLocation rlDest = getLoc(cUnit, inst);
2298 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2299 Instruction::Code opcode;
2300 if (rlDest.wide) {
2301 if (rlSrc.wide) {
2302 opcode = Instruction::LONG_TO_DOUBLE;
2303 } else {
2304 opcode = Instruction::INT_TO_DOUBLE;
2305 }
2306 } else {
2307 if (rlSrc.wide) {
2308 opcode = Instruction::LONG_TO_FLOAT;
2309 } else {
2310 opcode = Instruction::INT_TO_FLOAT;
2311 }
2312 }
2313 genConversion(cUnit, opcode, rlDest, rlSrc);
2314}
2315
TDYa1274ec8ccd2012-08-11 07:04:57 -07002316void cvtFPToInt(CompilationUnit* cUnit, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002317{
TDYa1274ec8ccd2012-08-11 07:04:57 -07002318 RegLocation rlDest = getLoc(cUnit, call_inst);
2319 RegLocation rlSrc = getLoc(cUnit, call_inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002320 Instruction::Code opcode;
2321 if (rlDest.wide) {
2322 if (rlSrc.wide) {
2323 opcode = Instruction::DOUBLE_TO_LONG;
2324 } else {
2325 opcode = Instruction::FLOAT_TO_LONG;
2326 }
2327 } else {
2328 if (rlSrc.wide) {
2329 opcode = Instruction::DOUBLE_TO_INT;
2330 } else {
2331 opcode = Instruction::FLOAT_TO_INT;
2332 }
2333 }
2334 genConversion(cUnit, opcode, rlDest, rlSrc);
2335}
2336
2337void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2338{
2339 RegLocation rlDest = getLoc(cUnit, inst);
2340 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2341 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2342}
2343
2344void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2345{
2346 RegLocation rlDest = getLoc(cUnit, inst);
2347 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2348 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2349 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2350 storeValue(cUnit, rlDest, rlSrc);
2351}
2352
2353void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2354{
2355 RegLocation rlDest = getLoc(cUnit, inst);
2356 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2357 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2358}
2359
2360
buzbee101305f2012-06-28 18:00:56 -07002361void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2362{
2363 // TODO: evaluate src/tgt types and add general support for more than int to long
2364 RegLocation rlDest = getLoc(cUnit, inst);
2365 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2366 DCHECK(rlDest.wide);
2367 DCHECK(!rlSrc.wide);
2368 DCHECK(!rlDest.fp);
2369 DCHECK(!rlSrc.fp);
2370 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2371 if (rlSrc.location == kLocPhysReg) {
2372 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2373 } else {
2374 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2375 }
2376 if (isSigned) {
2377 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2378 } else {
2379 loadConstant(cUnit, rlResult.highReg, 0);
2380 }
2381 storeValueWide(cUnit, rlDest, rlResult);
2382}
2383
buzbee2cfc6392012-05-07 14:51:40 -07002384void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2385{
2386 RegLocation rlDest = getLoc(cUnit, inst);
2387 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002388 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002389 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2390 if ((op == kOpSub) && (lhsImm != NULL)) {
2391 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002392 if (rlSrc1.wide) {
2393 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2394 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2395 } else {
2396 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2397 lhsImm->getSExtValue());
2398 }
buzbee4f1181f2012-06-22 13:52:12 -07002399 return;
2400 }
2401 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002402 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2403 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002404 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2405 if (!rlDest.wide && (constRhs != NULL)) {
buzbee2cfc6392012-05-07 14:51:40 -07002406 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
buzbee9a2487f2012-07-26 14:01:13 -07002407 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002408 } else {
2409 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002410 RegLocation rlSrc2;
2411 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002412 // ir_builder converts NOT_LONG to xor src, -1. Restore
2413 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2414 DCHECK_EQ(-1L, constRhs->getSExtValue());
2415 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002416 rlSrc2 = rlSrc1;
2417 } else {
2418 rlSrc2 = getLoc(cUnit, rhs);
2419 }
buzbee2cfc6392012-05-07 14:51:40 -07002420 if (rlDest.wide) {
2421 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2422 } else {
2423 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2424 }
2425 }
2426}
2427
buzbee2a83e8f2012-07-13 16:42:30 -07002428void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2429 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002430{
buzbee2a83e8f2012-07-13 16:42:30 -07002431 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2432 RegLocation rlDest = getLoc(cUnit, callInst);
2433 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2434 llvm::Value* rhs = callInst->getArgOperand(1);
2435 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2436 DCHECK(!rlDest.wide);
2437 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002438 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002439 RegLocation rlShift = getLoc(cUnit, rhs);
2440 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2441 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2442 } else {
2443 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2444 }
buzbee101305f2012-06-28 18:00:56 -07002445 }
2446}
2447
buzbee2cfc6392012-05-07 14:51:40 -07002448void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2449{
2450 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2451 DCHECK(brInst != NULL);
2452 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2453 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2454 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2455}
2456
2457void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2458{
2459 // Nop - these have already been processed
2460}
2461
2462void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2463{
2464 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2465 llvm::Value* retVal = retInst->getReturnValue();
2466 if (retVal != NULL) {
2467 RegLocation rlSrc = getLoc(cUnit, retVal);
2468 if (rlSrc.wide) {
2469 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2470 } else {
2471 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2472 }
2473 }
2474 genExitSequence(cUnit);
2475}
2476
2477ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2478{
2479 ConditionCode res = kCondAl;
2480 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002481 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002482 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2483 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2484 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002485 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002486 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002487 default: LOG(FATAL) << "Unexpected llvm condition";
2488 }
2489 return res;
2490}
2491
2492void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2493{
2494 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2495 UNIMPLEMENTED(FATAL);
2496}
2497
2498void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2499 llvm::BranchInst* brInst)
2500{
2501 // Get targets
2502 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2503 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2504 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2505 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2506 // Get comparison operands
2507 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2508 ConditionCode cond = getCond(iCmpInst->getPredicate());
2509 llvm::Value* lhs = iCmpInst->getOperand(0);
2510 // Not expecting a constant as 1st operand
2511 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2512 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2513 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2514 llvm::Value* rhs = inst->getOperand(1);
2515#if defined(TARGET_MIPS)
2516 // Compare and branch in one shot
2517 (void)taken;
2518 (void)cond;
2519 (void)rhs;
2520 UNIMPLEMENTED(FATAL);
2521#else
2522 //Compare, then branch
2523 // TODO: handle fused CMP_LONG/IF_xxZ case
2524 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2525 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002526 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2527 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002528 } else {
2529 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2530 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2531 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2532 }
2533 opCondBranch(cUnit, cond, taken);
2534#endif
2535 // Fallthrough
2536 opUnconditionalBranch(cUnit, fallThrough);
2537}
2538
2539void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2540 llvm::Function* callee)
2541{
2542 UNIMPLEMENTED(FATAL);
2543}
2544
buzbee2cfc6392012-05-07 14:51:40 -07002545void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2546{
buzbee4f1181f2012-06-22 13:52:12 -07002547 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002548 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2549 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002550 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2551 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002552 if (rlSrc.wide) {
2553 storeValueWide(cUnit, rlDest, rlSrc);
2554 } else {
2555 storeValue(cUnit, rlDest, rlSrc);
2556 }
2557}
2558
2559// Note: Immediate arg is a ConstantInt regardless of result type
2560void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2561{
buzbee4f1181f2012-06-22 13:52:12 -07002562 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002563 llvm::ConstantInt* src =
2564 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2565 uint64_t immval = src->getZExtValue();
2566 RegLocation rlDest = getLoc(cUnit, callInst);
2567 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2568 if (rlDest.wide) {
2569 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2570 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2571 storeValueWide(cUnit, rlDest, rlResult);
2572 } else {
2573 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2574 storeValue(cUnit, rlDest, rlResult);
2575 }
2576}
2577
buzbee101305f2012-06-28 18:00:56 -07002578void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2579 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002580{
buzbee4f1181f2012-06-22 13:52:12 -07002581 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002582 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002583 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002584 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002585 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002586 if (isString) {
2587 genConstString(cUnit, index, rlDest);
2588 } else {
2589 genConstClass(cUnit, index, rlDest);
2590 }
2591}
2592
2593void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2594{
2595 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2596 llvm::ConstantInt* offsetVal =
2597 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2598 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2599 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002600}
2601
buzbee4f1181f2012-06-22 13:52:12 -07002602void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2603{
buzbee32412962012-06-26 16:27:56 -07002604 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002605 llvm::ConstantInt* typeIdxVal =
2606 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2607 uint32_t typeIdx = typeIdxVal->getZExtValue();
2608 RegLocation rlDest = getLoc(cUnit, callInst);
2609 genNewInstance(cUnit, typeIdx, rlDest);
2610}
2611
buzbee8fa0fda2012-06-27 15:44:52 -07002612void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2613{
2614 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2615 llvm::ConstantInt* typeIdxVal =
2616 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2617 uint32_t typeIdx = typeIdxVal->getZExtValue();
2618 llvm::Value* len = callInst->getArgOperand(1);
2619 RegLocation rlLen = getLoc(cUnit, len);
2620 RegLocation rlDest = getLoc(cUnit, callInst);
2621 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2622}
2623
2624void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2625{
2626 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2627 llvm::ConstantInt* typeIdxVal =
2628 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2629 uint32_t typeIdx = typeIdxVal->getZExtValue();
2630 llvm::Value* src = callInst->getArgOperand(1);
2631 RegLocation rlSrc = getLoc(cUnit, src);
2632 RegLocation rlDest = getLoc(cUnit, callInst);
2633 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2634}
2635
buzbee32412962012-06-26 16:27:56 -07002636void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2637{
2638 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2639 llvm::Value* src = callInst->getArgOperand(0);
2640 RegLocation rlSrc = getLoc(cUnit, src);
2641 genThrow(cUnit, rlSrc);
2642}
2643
buzbee8fa0fda2012-06-27 15:44:52 -07002644void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2645 llvm::CallInst* callInst)
2646{
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 if (isEnter) {
2653 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2654 } else {
2655 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2656 }
2657}
2658
buzbee76592632012-06-29 15:18:35 -07002659void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002660{
2661 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2662 llvm::ConstantInt* optFlags =
2663 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2664 llvm::Value* src = callInst->getArgOperand(1);
2665 RegLocation rlSrc = getLoc(cUnit, src);
2666 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2667 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2668 RegLocation rlDest = getLoc(cUnit, callInst);
2669 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2670 int lenOffset = Array::LengthOffset().Int32Value();
2671 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2672 storeValue(cUnit, rlDest, rlResult);
2673}
2674
buzbee32412962012-06-26 16:27:56 -07002675void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2676{
buzbee32412962012-06-26 16:27:56 -07002677 RegLocation rlDest = getLoc(cUnit, callInst);
Ian Rogers474b6da2012-09-25 00:20:38 -07002678 genMoveException(cUnit, rlDest);
buzbee32412962012-06-26 16:27:56 -07002679}
2680
buzbee4f1181f2012-06-22 13:52:12 -07002681void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2682 bool isObject)
2683{
buzbee32412962012-06-26 16:27:56 -07002684 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002685 llvm::ConstantInt* typeIdxVal =
2686 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2687 uint32_t typeIdx = typeIdxVal->getZExtValue();
2688 RegLocation rlDest = getLoc(cUnit, callInst);
2689 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2690}
2691
buzbee8fa0fda2012-06-27 15:44:52 -07002692void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2693 bool isObject)
2694{
2695 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2696 llvm::ConstantInt* typeIdxVal =
2697 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2698 uint32_t typeIdx = typeIdxVal->getZExtValue();
2699 llvm::Value* src = callInst->getArgOperand(1);
2700 RegLocation rlSrc = getLoc(cUnit, src);
2701 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2702}
2703
2704void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2705 int scale)
2706{
2707 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2708 llvm::ConstantInt* optFlags =
2709 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2710 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2711 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2712 RegLocation rlDest = getLoc(cUnit, callInst);
2713 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2714 rlDest, scale);
2715}
2716
2717void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002718 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002719{
2720 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2721 llvm::ConstantInt* optFlags =
2722 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2723 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2724 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2725 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002726 if (isObject) {
2727 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2728 rlSrc, scale);
2729 } else {
2730 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2731 rlSrc, scale);
2732 }
2733}
2734
2735void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2736{
2737 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2738}
2739
2740void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2741 OpSize size, int scale)
2742{
2743 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002744}
2745
buzbee101305f2012-06-28 18:00:56 -07002746void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2747 bool isWide, bool isObj)
2748{
2749 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2750 llvm::ConstantInt* optFlags =
2751 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2752 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2753 llvm::ConstantInt* fieldIdx =
2754 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2755 RegLocation rlDest = getLoc(cUnit, callInst);
2756 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2757 size, rlDest, rlObj, isWide, isObj);
2758}
2759
2760void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2761 bool isWide, bool isObj)
2762{
2763 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2764 llvm::ConstantInt* optFlags =
2765 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2766 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2767 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2768 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002769 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002770 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2771 size, rlSrc, rlObj, isWide, isObj);
2772}
2773
2774void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2775{
2776 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2777 llvm::ConstantInt* typeIdx =
2778 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2779 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2780 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2781}
2782
buzbee76592632012-06-29 15:18:35 -07002783void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2784 Instruction::Code opcode)
2785{
2786 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2787 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2788 RegLocation rlDest = getLoc(cUnit, callInst);
2789 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2790}
2791
2792void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2793{
2794 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2795 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2796 RegLocation rlDest = getLoc(cUnit, callInst);
2797 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2798}
2799
buzbeef58c12c2012-07-03 15:06:29 -07002800void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2801{
2802 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2803 DCHECK(swInst != NULL);
2804 llvm::Value* testVal = swInst->getCondition();
2805 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2806 DCHECK(tableOffsetNode != NULL);
2807 llvm::ConstantInt* tableOffsetValue =
2808 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2809 int32_t tableOffset = tableOffsetValue->getSExtValue();
2810 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeea1da8a52012-07-09 14:00:21 -07002811 const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2812 u2 tableMagic = *table;
2813 if (tableMagic == 0x100) {
2814 genPackedSwitch(cUnit, tableOffset, rlSrc);
2815 } else {
2816 DCHECK_EQ(tableMagic, 0x200);
2817 genSparseSwitch(cUnit, tableOffset, rlSrc);
2818 }
buzbeef58c12c2012-07-03 15:06:29 -07002819}
2820
buzbee6969d502012-06-15 16:40:31 -07002821void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002822 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002823{
2824 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2825 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002826 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002827 info->result.location = kLocInvalid;
2828 } else {
2829 info->result = getLoc(cUnit, callInst);
2830 }
2831 llvm::ConstantInt* invokeTypeVal =
2832 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2833 llvm::ConstantInt* methodIndexVal =
2834 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2835 llvm::ConstantInt* optFlagsVal =
2836 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2837 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2838 info->index = methodIndexVal->getZExtValue();
2839 info->optFlags = optFlagsVal->getZExtValue();
2840 info->offset = cUnit->currentDalvikOffset;
2841
buzbee6969d502012-06-15 16:40:31 -07002842 // Count the argument words, and then build argument array.
2843 info->numArgWords = 0;
2844 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2845 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2846 info->numArgWords += tLoc.wide ? 2 : 1;
2847 }
2848 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2849 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2850 // Now, fill in the location records, synthesizing high loc of wide vals
2851 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002852 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002853 if (info->args[next].wide) {
2854 next++;
2855 // TODO: Might make sense to mark this as an invalid loc
2856 info->args[next].origSReg = info->args[next-1].origSReg+1;
2857 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2858 }
2859 next++;
2860 }
buzbee4f4dfc72012-07-02 14:54:44 -07002861 // TODO - rework such that we no longer need isRange
2862 info->isRange = (info->numArgWords > 5);
2863
buzbee76592632012-06-29 15:18:35 -07002864 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002865 genFilledNewArray(cUnit, info);
2866 } else {
2867 genInvoke(cUnit, info);
2868 }
buzbee6969d502012-06-15 16:40:31 -07002869}
2870
buzbeead8f15e2012-06-18 14:49:45 -07002871/* Look up the RegLocation associated with a Value. Must already be defined */
2872RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2873{
2874 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2875 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2876 return it->second;
2877}
2878
buzbee2cfc6392012-05-07 14:51:40 -07002879bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2880{
buzbee0967a252012-09-14 10:43:54 -07002881 while (cUnit->llvmBlocks.find(bb) == cUnit->llvmBlocks.end()) {
2882 llvm::BasicBlock* nextBB = NULL;
2883 cUnit->llvmBlocks.insert(bb);
2884 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2885 // Define the starting label
2886 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2887 // Extract the type and starting offset from the block's name
2888 char blockType = kNormalBlock;
2889 if (!isEntry) {
2890 const char* blockName = bb->getName().str().c_str();
2891 int dummy;
2892 sscanf(blockName, kLabelFormat, &blockType, &blockLabel->operands[0], &dummy);
2893 cUnit->currentDalvikOffset = blockLabel->operands[0];
2894 } else {
2895 cUnit->currentDalvikOffset = 0;
2896 }
2897 // Set the label kind
2898 blockLabel->opcode = kPseudoNormalBlockLabel;
2899 // Insert the label
2900 oatAppendLIR(cUnit, blockLabel);
buzbee2cfc6392012-05-07 14:51:40 -07002901
buzbee0967a252012-09-14 10:43:54 -07002902 LIR* headLIR = NULL;
buzbee8320f382012-09-11 16:29:42 -07002903
buzbee0967a252012-09-14 10:43:54 -07002904 if (blockType == kCatchBlock) {
Bill Buzbeea5b30242012-09-28 07:19:44 -07002905 headLIR = newLIR0(cUnit, kPseudoExportedPC);
buzbee0967a252012-09-14 10:43:54 -07002906 }
buzbee8320f382012-09-11 16:29:42 -07002907
buzbee0967a252012-09-14 10:43:54 -07002908 // Free temp registers and reset redundant store tracking */
2909 oatResetRegPool(cUnit);
2910 oatResetDefTracking(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002911
buzbee0967a252012-09-14 10:43:54 -07002912 //TODO: restore oat incoming liveness optimization
2913 oatClobberAllRegs(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002914
buzbee0967a252012-09-14 10:43:54 -07002915 if (isEntry) {
2916 RegLocation* argLocs = (RegLocation*)
2917 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2918 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2919 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2920 // Skip past Method*
2921 it++;
2922 for (unsigned i = 0; it != it_end; ++it) {
2923 llvm::Value* val = it;
2924 argLocs[i++] = valToLoc(cUnit, val);
2925 llvm::Type* ty = val->getType();
2926 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2927 argLocs[i] = argLocs[i-1];
2928 argLocs[i].lowReg = argLocs[i].highReg;
2929 argLocs[i].origSReg++;
2930 argLocs[i].sRegLow = INVALID_SREG;
2931 argLocs[i].highWord = true;
2932 i++;
2933 }
2934 }
2935 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
2936 }
2937
2938 // Visit all of the instructions in the block
2939 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2940 llvm::Instruction* inst = it;
2941 llvm::BasicBlock::iterator nextIt = ++it;
2942 // Extract the Dalvik offset from the instruction
2943 uint32_t opcode = inst->getOpcode();
2944 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2945 if (dexOffsetNode != NULL) {
2946 llvm::ConstantInt* dexOffsetValue =
2947 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2948 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2949 }
2950
2951 oatResetRegPool(cUnit);
2952 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2953 oatClobberAllRegs(cUnit);
2954 }
2955
2956 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2957 oatResetDefTracking(cUnit);
2958 }
2959
2960 #ifndef NDEBUG
2961 /* Reset temp tracking sanity check */
2962 cUnit->liveSReg = INVALID_SREG;
2963 #endif
2964
2965 // TODO: use llvm opcode name here instead of "boundary" if verbose
2966 LIR* boundaryLIR = markBoundary(cUnit, cUnit->currentDalvikOffset, "boundary");
2967
2968 /* Remember the first LIR for thisl block*/
2969 if (headLIR == NULL) {
2970 headLIR = boundaryLIR;
2971 headLIR->defMask = ENCODE_ALL;
2972 }
2973
2974 switch(opcode) {
2975
2976 case llvm::Instruction::ICmp: {
2977 llvm::Instruction* nextInst = nextIt;
2978 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2979 if (brInst != NULL /* and... */) {
2980 cvtICmpBr(cUnit, inst, brInst);
2981 ++it;
2982 } else {
2983 cvtICmp(cUnit, inst);
2984 }
2985 }
2986 break;
2987
2988 case llvm::Instruction::Call: {
2989 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2990 llvm::Function* callee = callInst->getCalledFunction();
2991 greenland::IntrinsicHelper::IntrinsicId id =
2992 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2993 switch (id) {
2994 case greenland::IntrinsicHelper::AllocaShadowFrame:
2995 case greenland::IntrinsicHelper::SetShadowFrameEntry:
2996 case greenland::IntrinsicHelper::PopShadowFrame:
2997 // Ignore shadow frame stuff for quick compiler
2998 break;
2999 case greenland::IntrinsicHelper::CopyInt:
3000 case greenland::IntrinsicHelper::CopyObj:
3001 case greenland::IntrinsicHelper::CopyFloat:
3002 case greenland::IntrinsicHelper::CopyLong:
3003 case greenland::IntrinsicHelper::CopyDouble:
3004 cvtCopy(cUnit, callInst);
3005 break;
3006 case greenland::IntrinsicHelper::ConstInt:
3007 case greenland::IntrinsicHelper::ConstObj:
3008 case greenland::IntrinsicHelper::ConstLong:
3009 case greenland::IntrinsicHelper::ConstFloat:
3010 case greenland::IntrinsicHelper::ConstDouble:
3011 cvtConst(cUnit, callInst);
3012 break;
3013 case greenland::IntrinsicHelper::DivInt:
3014 case greenland::IntrinsicHelper::DivLong:
3015 cvtBinOp(cUnit, kOpDiv, inst);
3016 break;
3017 case greenland::IntrinsicHelper::RemInt:
3018 case greenland::IntrinsicHelper::RemLong:
3019 cvtBinOp(cUnit, kOpRem, inst);
3020 break;
3021 case greenland::IntrinsicHelper::MethodInfo:
3022 // Already dealt with - just ignore it here.
3023 break;
3024 case greenland::IntrinsicHelper::CheckSuspend:
3025 genSuspendTest(cUnit, 0 /* optFlags already applied */);
3026 break;
3027 case greenland::IntrinsicHelper::HLInvokeObj:
3028 case greenland::IntrinsicHelper::HLInvokeFloat:
3029 case greenland::IntrinsicHelper::HLInvokeDouble:
3030 case greenland::IntrinsicHelper::HLInvokeLong:
3031 case greenland::IntrinsicHelper::HLInvokeInt:
3032 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
3033 break;
3034 case greenland::IntrinsicHelper::HLInvokeVoid:
3035 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
3036 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003037 case greenland::IntrinsicHelper::HLFilledNewArray:
buzbee0967a252012-09-14 10:43:54 -07003038 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
3039 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003040 case greenland::IntrinsicHelper::HLFillArrayData:
buzbee0967a252012-09-14 10:43:54 -07003041 cvtFillArrayData(cUnit, callInst);
3042 break;
3043 case greenland::IntrinsicHelper::ConstString:
3044 cvtConstObject(cUnit, callInst, true /* isString */);
3045 break;
3046 case greenland::IntrinsicHelper::ConstClass:
3047 cvtConstObject(cUnit, callInst, false /* isString */);
3048 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003049 case greenland::IntrinsicHelper::HLCheckCast:
buzbee0967a252012-09-14 10:43:54 -07003050 cvtCheckCast(cUnit, callInst);
3051 break;
3052 case greenland::IntrinsicHelper::NewInstance:
3053 cvtNewInstance(cUnit, callInst);
3054 break;
3055 case greenland::IntrinsicHelper::HLSgetObject:
3056 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
3057 break;
3058 case greenland::IntrinsicHelper::HLSget:
3059 case greenland::IntrinsicHelper::HLSgetFloat:
3060 case greenland::IntrinsicHelper::HLSgetBoolean:
3061 case greenland::IntrinsicHelper::HLSgetByte:
3062 case greenland::IntrinsicHelper::HLSgetChar:
3063 case greenland::IntrinsicHelper::HLSgetShort:
3064 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
3065 break;
3066 case greenland::IntrinsicHelper::HLSgetWide:
3067 case greenland::IntrinsicHelper::HLSgetDouble:
3068 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
3069 break;
3070 case greenland::IntrinsicHelper::HLSput:
3071 case greenland::IntrinsicHelper::HLSputFloat:
3072 case greenland::IntrinsicHelper::HLSputBoolean:
3073 case greenland::IntrinsicHelper::HLSputByte:
3074 case greenland::IntrinsicHelper::HLSputChar:
3075 case greenland::IntrinsicHelper::HLSputShort:
3076 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
3077 break;
3078 case greenland::IntrinsicHelper::HLSputWide:
3079 case greenland::IntrinsicHelper::HLSputDouble:
3080 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
3081 break;
3082 case greenland::IntrinsicHelper::HLSputObject:
3083 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
3084 break;
3085 case greenland::IntrinsicHelper::GetException:
3086 cvtMoveException(cUnit, callInst);
3087 break;
TDYa127f71bf5a2012-07-29 20:09:52 -07003088 case greenland::IntrinsicHelper::HLThrowException:
buzbee0967a252012-09-14 10:43:54 -07003089 cvtThrow(cUnit, callInst);
3090 break;
3091 case greenland::IntrinsicHelper::MonitorEnter:
3092 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
3093 break;
3094 case greenland::IntrinsicHelper::MonitorExit:
3095 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
3096 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003097 case greenland::IntrinsicHelper::OptArrayLength:
buzbee0967a252012-09-14 10:43:54 -07003098 cvtArrayLength(cUnit, callInst);
3099 break;
3100 case greenland::IntrinsicHelper::NewArray:
3101 cvtNewArray(cUnit, callInst);
3102 break;
3103 case greenland::IntrinsicHelper::InstanceOf:
3104 cvtInstanceOf(cUnit, callInst);
3105 break;
3106
3107 case greenland::IntrinsicHelper::HLArrayGet:
3108 case greenland::IntrinsicHelper::HLArrayGetObject:
3109 case greenland::IntrinsicHelper::HLArrayGetFloat:
3110 cvtAget(cUnit, callInst, kWord, 2);
3111 break;
3112 case greenland::IntrinsicHelper::HLArrayGetWide:
3113 case greenland::IntrinsicHelper::HLArrayGetDouble:
3114 cvtAget(cUnit, callInst, kLong, 3);
3115 break;
3116 case greenland::IntrinsicHelper::HLArrayGetBoolean:
3117 cvtAget(cUnit, callInst, kUnsignedByte, 0);
3118 break;
3119 case greenland::IntrinsicHelper::HLArrayGetByte:
3120 cvtAget(cUnit, callInst, kSignedByte, 0);
3121 break;
3122 case greenland::IntrinsicHelper::HLArrayGetChar:
3123 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
3124 break;
3125 case greenland::IntrinsicHelper::HLArrayGetShort:
3126 cvtAget(cUnit, callInst, kSignedHalf, 1);
3127 break;
3128
3129 case greenland::IntrinsicHelper::HLArrayPut:
3130 case greenland::IntrinsicHelper::HLArrayPutFloat:
3131 cvtAputPrimitive(cUnit, callInst, kWord, 2);
3132 break;
3133 case greenland::IntrinsicHelper::HLArrayPutObject:
3134 cvtAputObj(cUnit, callInst);
3135 break;
3136 case greenland::IntrinsicHelper::HLArrayPutWide:
3137 case greenland::IntrinsicHelper::HLArrayPutDouble:
3138 cvtAputPrimitive(cUnit, callInst, kLong, 3);
3139 break;
3140 case greenland::IntrinsicHelper::HLArrayPutBoolean:
3141 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
3142 break;
3143 case greenland::IntrinsicHelper::HLArrayPutByte:
3144 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
3145 break;
3146 case greenland::IntrinsicHelper::HLArrayPutChar:
3147 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
3148 break;
3149 case greenland::IntrinsicHelper::HLArrayPutShort:
3150 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
3151 break;
3152
3153 case greenland::IntrinsicHelper::HLIGet:
3154 case greenland::IntrinsicHelper::HLIGetFloat:
3155 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3156 break;
3157 case greenland::IntrinsicHelper::HLIGetObject:
3158 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3159 break;
3160 case greenland::IntrinsicHelper::HLIGetWide:
3161 case greenland::IntrinsicHelper::HLIGetDouble:
3162 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3163 break;
3164 case greenland::IntrinsicHelper::HLIGetBoolean:
3165 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3166 false /* obj */);
3167 break;
3168 case greenland::IntrinsicHelper::HLIGetByte:
3169 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3170 false /* obj */);
3171 break;
3172 case greenland::IntrinsicHelper::HLIGetChar:
3173 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3174 false /* obj */);
3175 break;
3176 case greenland::IntrinsicHelper::HLIGetShort:
3177 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3178 false /* obj */);
3179 break;
3180
3181 case greenland::IntrinsicHelper::HLIPut:
3182 case greenland::IntrinsicHelper::HLIPutFloat:
3183 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3184 break;
3185 case greenland::IntrinsicHelper::HLIPutObject:
3186 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3187 break;
3188 case greenland::IntrinsicHelper::HLIPutWide:
3189 case greenland::IntrinsicHelper::HLIPutDouble:
3190 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3191 break;
3192 case greenland::IntrinsicHelper::HLIPutBoolean:
3193 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3194 false /* obj */);
3195 break;
3196 case greenland::IntrinsicHelper::HLIPutByte:
3197 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3198 false /* obj */);
3199 break;
3200 case greenland::IntrinsicHelper::HLIPutChar:
3201 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3202 false /* obj */);
3203 break;
3204 case greenland::IntrinsicHelper::HLIPutShort:
3205 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3206 false /* obj */);
3207 break;
3208
3209 case greenland::IntrinsicHelper::IntToChar:
3210 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3211 break;
3212 case greenland::IntrinsicHelper::IntToShort:
3213 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3214 break;
3215 case greenland::IntrinsicHelper::IntToByte:
3216 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3217 break;
3218
TDYa1274ec8ccd2012-08-11 07:04:57 -07003219 case greenland::IntrinsicHelper::F2I:
3220 case greenland::IntrinsicHelper::D2I:
3221 case greenland::IntrinsicHelper::F2L:
3222 case greenland::IntrinsicHelper::D2L:
3223 cvtFPToInt(cUnit, callInst);
3224 break;
3225
buzbee0967a252012-09-14 10:43:54 -07003226 case greenland::IntrinsicHelper::CmplFloat:
3227 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3228 break;
3229 case greenland::IntrinsicHelper::CmpgFloat:
3230 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3231 break;
3232 case greenland::IntrinsicHelper::CmplDouble:
3233 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3234 break;
3235 case greenland::IntrinsicHelper::CmpgDouble:
3236 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3237 break;
3238
3239 case greenland::IntrinsicHelper::CmpLong:
3240 cvtLongCompare(cUnit, callInst);
3241 break;
3242
3243 case greenland::IntrinsicHelper::SHLLong:
3244 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
3245 break;
3246 case greenland::IntrinsicHelper::SHRLong:
3247 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3248 break;
3249 case greenland::IntrinsicHelper::USHRLong:
3250 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3251 break;
3252 case greenland::IntrinsicHelper::SHLInt:
3253 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3254 break;
3255 case greenland::IntrinsicHelper::SHRInt:
3256 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3257 break;
3258 case greenland::IntrinsicHelper::USHRInt:
3259 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3260 break;
3261
3262 case greenland::IntrinsicHelper::CatchTargets: {
3263 llvm::SwitchInst* swInst =
3264 llvm::dyn_cast<llvm::SwitchInst>(nextIt);
3265 DCHECK(swInst != NULL);
3266 /*
3267 * Discard the edges and the following conditional branch.
3268 * Do a direct branch to the default target (which is the
3269 * "work" portion of the pair.
3270 * TODO: awful code layout - rework
3271 */
3272 llvm::BasicBlock* targetBB = swInst->getDefaultDest();
3273 DCHECK(targetBB != NULL);
3274 opUnconditionalBranch(cUnit,
3275 cUnit->blockToLabelMap.Get(targetBB));
3276 ++it;
3277 // Set next bb to default target - improves code layout
3278 nextBB = targetBB;
3279 }
3280 break;
3281
3282 default:
3283 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3284 << cUnit->intrinsic_helper->GetName(id);
3285 }
3286 }
3287 break;
3288
3289 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3290 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3291 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3292 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3293 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3294 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3295 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3296 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3297 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
3298 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3299 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
3300 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3301 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3302 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3303 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3304 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
3305 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003306 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3307 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3308 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
3309
3310 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3311 break;
3312 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3313 break;
3314
3315 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3316
3317 case llvm::Instruction::Unreachable:
3318 break; // FIXME: can we really ignore these?
3319
3320 case llvm::Instruction::Shl:
3321 case llvm::Instruction::LShr:
3322 case llvm::Instruction::AShr:
3323 case llvm::Instruction::Invoke:
3324 case llvm::Instruction::FPToUI:
TDYa1274ec8ccd2012-08-11 07:04:57 -07003325 case llvm::Instruction::FPToSI:
buzbee0967a252012-09-14 10:43:54 -07003326 case llvm::Instruction::UIToFP:
3327 case llvm::Instruction::PtrToInt:
3328 case llvm::Instruction::IntToPtr:
3329 case llvm::Instruction::FCmp:
3330 case llvm::Instruction::URem:
3331 case llvm::Instruction::UDiv:
3332 case llvm::Instruction::Resume:
3333 case llvm::Instruction::Alloca:
3334 case llvm::Instruction::GetElementPtr:
3335 case llvm::Instruction::Fence:
3336 case llvm::Instruction::AtomicCmpXchg:
3337 case llvm::Instruction::AtomicRMW:
3338 case llvm::Instruction::BitCast:
3339 case llvm::Instruction::VAArg:
3340 case llvm::Instruction::Select:
3341 case llvm::Instruction::UserOp1:
3342 case llvm::Instruction::UserOp2:
3343 case llvm::Instruction::ExtractElement:
3344 case llvm::Instruction::InsertElement:
3345 case llvm::Instruction::ShuffleVector:
3346 case llvm::Instruction::ExtractValue:
3347 case llvm::Instruction::InsertValue:
3348 case llvm::Instruction::LandingPad:
3349 case llvm::Instruction::IndirectBr:
3350 case llvm::Instruction::Load:
3351 case llvm::Instruction::Store:
3352 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3353
3354 default:
3355 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3356 break;
buzbeead8f15e2012-06-18 14:49:45 -07003357 }
3358 }
buzbee2cfc6392012-05-07 14:51:40 -07003359
buzbee0967a252012-09-14 10:43:54 -07003360 if (headLIR != NULL) {
3361 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
buzbee2cfc6392012-05-07 14:51:40 -07003362 }
buzbee0967a252012-09-14 10:43:54 -07003363 if (nextBB != NULL) {
3364 bb = nextBB;
3365 nextBB = NULL;
buzbee6969d502012-06-15 16:40:31 -07003366 }
buzbee6969d502012-06-15 16:40:31 -07003367 }
buzbee2cfc6392012-05-07 14:51:40 -07003368 return false;
3369}
3370
3371/*
3372 * Convert LLVM_IR to MIR:
3373 * o Iterate through the LLVM_IR and construct a graph using
3374 * standard MIR building blocks.
3375 * o Perform a basic-block optimization pass to remove unnecessary
3376 * store/load sequences.
3377 * o Convert the LLVM Value operands into RegLocations where applicable.
3378 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3379 * o Perform register promotion
3380 * o Iterate through the graph a basic block at a time, generating
3381 * LIR.
3382 * o Assemble LIR as usual.
3383 * o Profit.
3384 */
3385void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3386{
buzbeead8f15e2012-06-18 14:49:45 -07003387 llvm::Function* func = cUnit->func;
3388 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003389 // Allocate a list for LIR basic block labels
3390 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07003391 (LIR*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3392 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003393 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003394 for (llvm::Function::iterator i = func->begin(),
3395 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003396 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3397 &labelList[nextLabel++]);
3398 }
buzbeead8f15e2012-06-18 14:49:45 -07003399
3400 /*
3401 * Keep honest - clear regLocations, Value => RegLocation,
3402 * promotion map and VmapTables.
3403 */
3404 cUnit->locMap.clear(); // Start fresh
3405 cUnit->regLocation = NULL;
3406 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3407 i++) {
3408 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3409 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3410 }
3411 cUnit->coreSpillMask = 0;
3412 cUnit->numCoreSpills = 0;
3413 cUnit->fpSpillMask = 0;
3414 cUnit->numFPSpills = 0;
3415 cUnit->coreVmapTable.clear();
3416 cUnit->fpVmapTable.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003417
3418 /*
3419 * At this point, we've lost all knowledge of register promotion.
3420 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003421 * exists - not required for correctness). Normally, this will
3422 * be the first instruction we encounter, so we won't have to iterate
3423 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003424 */
buzbeeca7a5e42012-08-20 11:12:18 -07003425 for (llvm::inst_iterator i = llvm::inst_begin(func),
3426 e = llvm::inst_end(func); i != e; ++i) {
3427 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(&*i);
3428 if (callInst != NULL) {
3429 llvm::Function* callee = callInst->getCalledFunction();
3430 greenland::IntrinsicHelper::IntrinsicId id =
3431 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3432 if (id == greenland::IntrinsicHelper::MethodInfo) {
3433 if (cUnit->printMe) {
3434 LOG(INFO) << "Found MethodInfo";
3435 }
3436 llvm::MDNode* regInfoNode = callInst->getMetadata("RegInfo");
3437 if (regInfoNode != NULL) {
3438 llvm::ConstantInt* numInsValue =
3439 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(0));
3440 llvm::ConstantInt* numRegsValue =
3441 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(1));
3442 llvm::ConstantInt* numOutsValue =
3443 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(2));
3444 llvm::ConstantInt* numCompilerTempsValue =
3445 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(3));
3446 llvm::ConstantInt* numSSARegsValue =
3447 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(4));
3448 if (cUnit->printMe) {
3449 LOG(INFO) << "RegInfo - Ins:" << numInsValue->getZExtValue()
3450 << ", Regs:" << numRegsValue->getZExtValue()
3451 << ", Outs:" << numOutsValue->getZExtValue()
3452 << ", CTemps:" << numCompilerTempsValue->getZExtValue()
3453 << ", SSARegs:" << numSSARegsValue->getZExtValue();
3454 }
3455 }
3456 llvm::MDNode* pmapInfoNode = callInst->getMetadata("PromotionMap");
3457 if (pmapInfoNode != NULL) {
3458 int elems = pmapInfoNode->getNumOperands();
3459 if (cUnit->printMe) {
3460 LOG(INFO) << "PMap size: " << elems;
3461 }
3462 for (int i = 0; i < elems; i++) {
3463 llvm::ConstantInt* rawMapData =
3464 static_cast<llvm::ConstantInt*>(pmapInfoNode->getOperand(i));
3465 uint32_t mapData = rawMapData->getZExtValue();
3466 PromotionMap* p = &cUnit->promotionMap[i];
3467 p->firstInPair = (mapData >> 24) & 0xff;
3468 p->fpReg = (mapData >> 16) & 0xff;
3469 p->coreReg = (mapData >> 8) & 0xff;
3470 p->fpLocation = static_cast<RegLocationType>((mapData >> 4) & 0xf);
3471 if (p->fpLocation == kLocPhysReg) {
3472 oatRecordFpPromotion(cUnit, p->fpReg, i);
3473 }
3474 p->coreLocation = static_cast<RegLocationType>(mapData & 0xf);
3475 if (p->coreLocation == kLocPhysReg) {
3476 oatRecordCorePromotion(cUnit, p->coreReg, i);
3477 }
3478 }
3479 if (cUnit->printMe) {
3480 oatDumpPromotionMap(cUnit);
3481 }
3482 }
3483 break;
3484 }
3485 }
3486 }
3487 oatAdjustSpillMask(cUnit);
3488 cUnit->frameSize = oatComputeFrameSize(cUnit);
buzbeead8f15e2012-06-18 14:49:45 -07003489
3490 // Create RegLocations for arguments
3491 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3492 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3493 for (; it != it_end; ++it) {
3494 llvm::Value* val = it;
3495 createLocFromValue(cUnit, val);
3496 }
3497 // Create RegLocations for all non-argument defintions
3498 for (llvm::inst_iterator i = llvm::inst_begin(func),
3499 e = llvm::inst_end(func); i != e; ++i) {
3500 llvm::Value* val = &*i;
3501 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3502 createLocFromValue(cUnit, val);
3503 }
3504 }
3505
buzbee2cfc6392012-05-07 14:51:40 -07003506 // Walk the blocks, generating code.
3507 for (llvm::Function::iterator i = cUnit->func->begin(),
3508 e = cUnit->func->end(); i != e; ++i) {
3509 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3510 }
3511
3512 handleSuspendLaunchpads(cUnit);
3513
3514 handleThrowLaunchpads(cUnit);
3515
3516 handleIntrinsicLaunchpads(cUnit);
3517
buzbee692be802012-08-29 15:52:59 -07003518 cUnit->func->eraseFromParent();
3519 cUnit->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003520}
3521
3522
3523} // namespace art
3524
3525#endif // ART_USE_QUICK_COMPILER