blob: 682de7ad6a99764c24c55cdfb1a29de561d56999 [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 }
buzbeeb03f4872012-06-11 15:22:11 -0700543 greenland::IntrinsicHelper::IntrinsicId id =
544 greenland::IntrinsicHelper::SetShadowFrameEntry;
545 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
546 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
547 llvm::Value* args[] = { newVal, tableSlot };
548 cUnit->irb->CreateCall(func, args);
549}
550
buzbee2cfc6392012-05-07 14:51:40 -0700551void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
552 RegLocation rlSrc1, int32_t imm)
553{
554 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
555 llvm::Value* src2 = cUnit->irb->getInt32(imm);
556 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
557 defineValue(cUnit, res, rlDest.origSReg);
558}
559
buzbee101305f2012-06-28 18:00:56 -0700560/*
561 * Process arguments for invoke. Note: this code is also used to
562 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
563 * The requirements are similar.
564 */
buzbee6969d502012-06-15 16:40:31 -0700565void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700566 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700567{
568 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
569 llvm::SmallVector<llvm::Value*, 10> args;
570 // Insert the invokeType
571 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
572 // Insert the method_idx
573 args.push_back(cUnit->irb->getInt32(info->index));
574 // Insert the optimization flags
575 args.push_back(cUnit->irb->getInt32(info->optFlags));
576 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700577 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700578 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
579 args.push_back(val);
580 i += info->args[i].wide ? 2 : 1;
581 }
582 /*
583 * Choose the invoke return type based on actual usage. Note: may
584 * be different than shorty. For example, if a function return value
585 * is not used, we'll treat this as a void invoke.
586 */
587 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700588 if (isFilledNewArray) {
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700589 id = greenland::IntrinsicHelper::HLFilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700590 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700591 id = greenland::IntrinsicHelper::HLInvokeVoid;
592 } else {
593 if (info->result.wide) {
594 if (info->result.fp) {
595 id = greenland::IntrinsicHelper::HLInvokeDouble;
596 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700597 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700598 }
599 } else if (info->result.ref) {
600 id = greenland::IntrinsicHelper::HLInvokeObj;
601 } else if (info->result.fp) {
602 id = greenland::IntrinsicHelper::HLInvokeFloat;
603 } else {
604 id = greenland::IntrinsicHelper::HLInvokeInt;
605 }
606 }
607 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
608 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
609 if (info->result.location != kLocInvalid) {
610 defineValue(cUnit, res, info->result.origSReg);
TDYa127890ea892012-08-22 10:49:42 -0700611 if (info->result.ref) {
612 setShadowFrameEntry(cUnit, (llvm::Value*)
613 cUnit->llvmValues.elemList[info->result.origSReg]);
614 }
buzbee6969d502012-06-15 16:40:31 -0700615 }
616}
617
buzbee101305f2012-06-28 18:00:56 -0700618void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
619 greenland::IntrinsicHelper::IntrinsicId id,
620 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700621{
buzbee6969d502012-06-15 16:40:31 -0700622 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700623 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700624 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
625 defineValue(cUnit, res, rlDest.origSReg);
626}
627
buzbee101305f2012-06-28 18:00:56 -0700628void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
629 RegLocation rlSrc)
630{
631 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700632 id = greenland::IntrinsicHelper::HLCheckCast;
buzbee101305f2012-06-28 18:00:56 -0700633 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
634 llvm::SmallVector<llvm::Value*, 2> args;
635 args.push_back(cUnit->irb->getInt32(type_idx));
636 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
637 cUnit->irb->CreateCall(intr, args);
638}
639
buzbee8fa0fda2012-06-27 15:44:52 -0700640void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
641 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700642{
643 greenland::IntrinsicHelper::IntrinsicId id;
644 id = greenland::IntrinsicHelper::NewInstance;
645 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
646 llvm::Value* index = cUnit->irb->getInt32(type_idx);
647 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
648 defineValue(cUnit, res, rlDest.origSReg);
649}
650
buzbee8fa0fda2012-06-27 15:44:52 -0700651void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
652 RegLocation rlDest, RegLocation rlSrc)
653{
654 greenland::IntrinsicHelper::IntrinsicId id;
655 id = greenland::IntrinsicHelper::NewArray;
656 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
657 llvm::SmallVector<llvm::Value*, 2> args;
658 args.push_back(cUnit->irb->getInt32(type_idx));
659 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
660 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
661 defineValue(cUnit, res, rlDest.origSReg);
662}
663
664void convertAget(CompilationUnit* cUnit, int optFlags,
665 greenland::IntrinsicHelper::IntrinsicId id,
666 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
667{
668 llvm::SmallVector<llvm::Value*, 3> args;
669 args.push_back(cUnit->irb->getInt32(optFlags));
670 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
671 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
672 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
673 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
674 defineValue(cUnit, res, rlDest.origSReg);
675}
676
677void convertAput(CompilationUnit* cUnit, int optFlags,
678 greenland::IntrinsicHelper::IntrinsicId id,
679 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
680{
681 llvm::SmallVector<llvm::Value*, 4> args;
682 args.push_back(cUnit->irb->getInt32(optFlags));
683 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
684 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
685 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
686 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
687 cUnit->irb->CreateCall(intr, args);
688}
689
buzbee101305f2012-06-28 18:00:56 -0700690void convertIget(CompilationUnit* cUnit, int optFlags,
691 greenland::IntrinsicHelper::IntrinsicId id,
692 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
693{
694 llvm::SmallVector<llvm::Value*, 3> args;
695 args.push_back(cUnit->irb->getInt32(optFlags));
696 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
697 args.push_back(cUnit->irb->getInt32(fieldIndex));
698 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
699 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
700 defineValue(cUnit, res, rlDest.origSReg);
701}
702
703void convertIput(CompilationUnit* cUnit, int optFlags,
704 greenland::IntrinsicHelper::IntrinsicId id,
705 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
706{
707 llvm::SmallVector<llvm::Value*, 4> args;
708 args.push_back(cUnit->irb->getInt32(optFlags));
709 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
710 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
711 args.push_back(cUnit->irb->getInt32(fieldIndex));
712 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
713 cUnit->irb->CreateCall(intr, args);
714}
715
buzbee8fa0fda2012-06-27 15:44:52 -0700716void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
717 RegLocation rlDest, RegLocation rlSrc)
718{
719 greenland::IntrinsicHelper::IntrinsicId id;
720 id = greenland::IntrinsicHelper::InstanceOf;
721 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
722 llvm::SmallVector<llvm::Value*, 2> args;
723 args.push_back(cUnit->irb->getInt32(type_idx));
724 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
725 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
726 defineValue(cUnit, res, rlDest.origSReg);
727}
728
buzbee101305f2012-06-28 18:00:56 -0700729void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
730 RegLocation rlSrc)
731{
732 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
733 cUnit->irb->getInt64Ty());
734 defineValue(cUnit, res, rlDest.origSReg);
735}
736
buzbee76592632012-06-29 15:18:35 -0700737void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
738 RegLocation rlSrc)
739{
740 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
741 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
742 defineValue(cUnit, res, rlDest.origSReg);
743}
744
745void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
746 RegLocation rlSrc)
747{
748 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
749 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
750 defineValue(cUnit, res, rlDest.origSReg);
751}
752
753void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
754 RegLocation rlSrc)
755{
756 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
757 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
758 defineValue(cUnit, res, rlDest.origSReg);
759}
760
761void convertWideComparison(CompilationUnit* cUnit,
762 greenland::IntrinsicHelper::IntrinsicId id,
763 RegLocation rlDest, RegLocation rlSrc1,
764 RegLocation rlSrc2)
765{
766 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
767 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
768 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
769 llvm::SmallVector<llvm::Value*, 2> args;
770 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
771 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
772 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
773 defineValue(cUnit, res, rlDest.origSReg);
774}
775
buzbee101305f2012-06-28 18:00:56 -0700776void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
777 RegLocation rlSrc,
778 greenland::IntrinsicHelper::IntrinsicId id)
779{
780 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700781 llvm::Value* res =
782 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
783 defineValue(cUnit, res, rlDest.origSReg);
784}
785
786void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
787 RegLocation rlSrc)
788{
789 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
790 defineValue(cUnit, res, rlDest.origSReg);
791}
792
793void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
794 RegLocation rlSrc)
795{
796 llvm::Value* res =
797 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
798 defineValue(cUnit, res, rlDest.origSReg);
799}
800
TDYa1274ec8ccd2012-08-11 07:04:57 -0700801void convertFPToInt(CompilationUnit* cUnit,
802 greenland::IntrinsicHelper::IntrinsicId id,
803 RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700804 RegLocation rlSrc)
805{
TDYa1274ec8ccd2012-08-11 07:04:57 -0700806 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
807 llvm::Value* res = cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
buzbee76592632012-06-29 15:18:35 -0700808 defineValue(cUnit, res, rlDest.origSReg);
809}
810
811
812void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
813 RegLocation rlSrc)
814{
815 llvm::Value* res =
816 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
817 defineValue(cUnit, res, rlDest.origSReg);
818}
819
820void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
821 RegLocation rlSrc)
822{
823 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
824 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700825 defineValue(cUnit, res, rlDest.origSReg);
826}
827
buzbee2cfc6392012-05-07 14:51:40 -0700828/*
829 * Target-independent code generation. Use only high-level
830 * load/store utilities here, or target-dependent genXX() handlers
831 * when necessary.
832 */
833bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
834 llvm::BasicBlock* llvmBB, LIR* labelList)
835{
836 bool res = false; // Assume success
837 RegLocation rlSrc[3];
838 RegLocation rlDest = badLoc;
buzbee2cfc6392012-05-07 14:51:40 -0700839 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee6969d502012-06-15 16:40:31 -0700840 uint32_t vB = mir->dalvikInsn.vB;
841 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700842 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700843
buzbeeb03f4872012-06-11 15:22:11 -0700844 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700845
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700846 if (cUnit->printMe) {
847 if ((int)opcode < kMirOpFirst) {
848 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x"
849 << std::hex << (int)opcode;
850 } else {
851 LOG(INFO) << ".. opcode 0x" << std::hex << (int)opcode;
852 }
853 }
854
buzbee2cfc6392012-05-07 14:51:40 -0700855 /* Prep Src and Dest locations */
856 int nextSreg = 0;
857 int nextLoc = 0;
858 int attrs = oatDataFlowAttributes[opcode];
859 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
860 if (attrs & DF_UA) {
861 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700862 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700863 nextSreg+= 2;
864 } else {
865 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
866 nextSreg++;
867 }
868 }
869 if (attrs & DF_UB) {
870 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700871 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700872 nextSreg+= 2;
873 } else {
874 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
875 nextSreg++;
876 }
877 }
878 if (attrs & DF_UC) {
879 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700880 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700881 } else {
882 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
883 }
884 }
885 if (attrs & DF_DA) {
886 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700887 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700888 } else {
buzbee15bf9802012-06-12 17:49:27 -0700889 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700890 if (rlDest.ref) {
891 objectDefinition = true;
892 }
buzbee2cfc6392012-05-07 14:51:40 -0700893 }
894 }
895
896 switch (opcode) {
897 case Instruction::NOP:
898 break;
899
900 case Instruction::MOVE:
901 case Instruction::MOVE_OBJECT:
902 case Instruction::MOVE_16:
903 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700904 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700905 case Instruction::MOVE_FROM16:
906 case Instruction::MOVE_WIDE:
907 case Instruction::MOVE_WIDE_16:
908 case Instruction::MOVE_WIDE_FROM16: {
909 /*
910 * Moves/copies are meaningless in pure SSA register form,
911 * but we need to preserve them for the conversion back into
912 * MIR (at least until we stop using the Dalvik register maps).
913 * Insert a dummy intrinsic copy call, which will be recognized
914 * by the quick path and removed by the portable path.
915 */
916 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
917 llvm::Value* res = emitCopy(cUnit, src, rlDest);
918 defineValue(cUnit, res, rlDest.origSReg);
919 }
920 break;
921
922 case Instruction::CONST:
923 case Instruction::CONST_4:
924 case Instruction::CONST_16: {
TDYa127347166a2012-08-23 12:23:44 -0700925 if (vB == 0) {
926 objectDefinition = true;
927 }
buzbee6969d502012-06-15 16:40:31 -0700928 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700929 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
930 defineValue(cUnit, res, rlDest.origSReg);
931 }
932 break;
933
934 case Instruction::CONST_WIDE_16:
935 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700936 // Sign extend to 64 bits
937 int64_t imm = static_cast<int32_t>(vB);
938 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700939 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
940 defineValue(cUnit, res, rlDest.origSReg);
941 }
942 break;
943
944 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700945 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700946 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
947 defineValue(cUnit, res, rlDest.origSReg);
948 }
949 break;
950
951 case Instruction::CONST_WIDE: {
952 llvm::Constant* immValue =
953 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
954 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
955 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700956 }
957 break;
buzbee2cfc6392012-05-07 14:51:40 -0700958 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700959 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700960 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
961 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
962 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700963 }
964 break;
965
buzbee8fa0fda2012-06-27 15:44:52 -0700966 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700967 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700968 rlSrc[0]);
969 break;
970 case Instruction::SPUT:
971 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700972 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700973 rlSrc[0]);
974 } else {
buzbee76592632012-06-29 15:18:35 -0700975 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700976 }
977 break;
978 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700979 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700980 rlSrc[0]);
981 break;
982 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700983 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700984 break;
985 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700986 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700987 break;
988 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -0700989 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700990 break;
991 case Instruction::SPUT_WIDE:
992 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700993 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -0700994 rlSrc[0]);
995 } else {
buzbee76592632012-06-29 15:18:35 -0700996 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -0700997 rlSrc[0]);
998 }
999 break;
1000
1001 case Instruction::SGET_OBJECT:
1002 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
1003 break;
1004 case Instruction::SGET:
1005 if (rlDest.fp) {
1006 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
1007 } else {
1008 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
1009 }
1010 break;
1011 case Instruction::SGET_BOOLEAN:
1012 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
1013 break;
1014 case Instruction::SGET_BYTE:
1015 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
1016 break;
1017 case Instruction::SGET_CHAR:
1018 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
1019 break;
1020 case Instruction::SGET_SHORT:
1021 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
1022 break;
1023 case Instruction::SGET_WIDE:
1024 if (rlDest.fp) {
1025 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
1026 rlDest);
1027 } else {
1028 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001029 }
1030 break;
buzbee2cfc6392012-05-07 14:51:40 -07001031
1032 case Instruction::RETURN_WIDE:
1033 case Instruction::RETURN:
1034 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -07001035 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001036 emitSuspendCheck(cUnit);
1037 }
buzbeeb03f4872012-06-11 15:22:11 -07001038 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001039 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
1040 bb->hasReturn = true;
1041 }
1042 break;
1043
1044 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001045 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001046 emitSuspendCheck(cUnit);
1047 }
buzbeeb03f4872012-06-11 15:22:11 -07001048 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001049 cUnit->irb->CreateRetVoid();
1050 bb->hasReturn = true;
1051 }
1052 break;
1053
1054 case Instruction::IF_EQ:
1055 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1056 break;
1057 case Instruction::IF_NE:
1058 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1059 break;
1060 case Instruction::IF_LT:
1061 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1062 break;
1063 case Instruction::IF_GE:
1064 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1065 break;
1066 case Instruction::IF_GT:
1067 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1068 break;
1069 case Instruction::IF_LE:
1070 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1071 break;
1072 case Instruction::IF_EQZ:
1073 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1074 break;
1075 case Instruction::IF_NEZ:
1076 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1077 break;
1078 case Instruction::IF_LTZ:
1079 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1080 break;
1081 case Instruction::IF_GEZ:
1082 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1083 break;
1084 case Instruction::IF_GTZ:
1085 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1086 break;
1087 case Instruction::IF_LEZ:
1088 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1089 break;
1090
1091 case Instruction::GOTO:
1092 case Instruction::GOTO_16:
1093 case Instruction::GOTO_32: {
1094 if (bb->taken->startOffset <= bb->startOffset) {
1095 emitSuspendCheck(cUnit);
1096 }
1097 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1098 }
1099 break;
1100
1101 case Instruction::ADD_LONG:
1102 case Instruction::ADD_LONG_2ADDR:
1103 case Instruction::ADD_INT:
1104 case Instruction::ADD_INT_2ADDR:
1105 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1106 break;
1107 case Instruction::SUB_LONG:
1108 case Instruction::SUB_LONG_2ADDR:
1109 case Instruction::SUB_INT:
1110 case Instruction::SUB_INT_2ADDR:
1111 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1112 break;
1113 case Instruction::MUL_LONG:
1114 case Instruction::MUL_LONG_2ADDR:
1115 case Instruction::MUL_INT:
1116 case Instruction::MUL_INT_2ADDR:
1117 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1118 break;
1119 case Instruction::DIV_LONG:
1120 case Instruction::DIV_LONG_2ADDR:
1121 case Instruction::DIV_INT:
1122 case Instruction::DIV_INT_2ADDR:
1123 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1124 break;
1125 case Instruction::REM_LONG:
1126 case Instruction::REM_LONG_2ADDR:
1127 case Instruction::REM_INT:
1128 case Instruction::REM_INT_2ADDR:
1129 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1130 break;
1131 case Instruction::AND_LONG:
1132 case Instruction::AND_LONG_2ADDR:
1133 case Instruction::AND_INT:
1134 case Instruction::AND_INT_2ADDR:
1135 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1136 break;
1137 case Instruction::OR_LONG:
1138 case Instruction::OR_LONG_2ADDR:
1139 case Instruction::OR_INT:
1140 case Instruction::OR_INT_2ADDR:
1141 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1142 break;
1143 case Instruction::XOR_LONG:
1144 case Instruction::XOR_LONG_2ADDR:
1145 case Instruction::XOR_INT:
1146 case Instruction::XOR_INT_2ADDR:
1147 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1148 break;
1149 case Instruction::SHL_LONG:
1150 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001151 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1152 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001153 break;
buzbee2cfc6392012-05-07 14:51:40 -07001154 case Instruction::SHL_INT:
1155 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001156 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1157 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001158 break;
1159 case Instruction::SHR_LONG:
1160 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001161 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1162 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001163 break;
buzbee2cfc6392012-05-07 14:51:40 -07001164 case Instruction::SHR_INT:
1165 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001166 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1167 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001168 break;
1169 case Instruction::USHR_LONG:
1170 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001171 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1172 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001173 break;
buzbee2cfc6392012-05-07 14:51:40 -07001174 case Instruction::USHR_INT:
1175 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001176 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1177 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001178 break;
1179
1180 case Instruction::ADD_INT_LIT16:
1181 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001182 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001183 break;
1184 case Instruction::RSUB_INT:
1185 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001186 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001187 break;
1188 case Instruction::MUL_INT_LIT16:
1189 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001190 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001191 break;
1192 case Instruction::DIV_INT_LIT16:
1193 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001194 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001195 break;
1196 case Instruction::REM_INT_LIT16:
1197 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001198 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001199 break;
1200 case Instruction::AND_INT_LIT16:
1201 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001202 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001203 break;
1204 case Instruction::OR_INT_LIT16:
1205 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001206 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001207 break;
1208 case Instruction::XOR_INT_LIT16:
1209 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001210 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001211 break;
1212 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001213 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1214 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001215 break;
1216 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001217 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1218 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001219 break;
1220 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001221 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1222 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001223 break;
1224
1225 case Instruction::ADD_FLOAT:
1226 case Instruction::ADD_FLOAT_2ADDR:
1227 case Instruction::ADD_DOUBLE:
1228 case Instruction::ADD_DOUBLE_2ADDR:
1229 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1230 break;
1231
1232 case Instruction::SUB_FLOAT:
1233 case Instruction::SUB_FLOAT_2ADDR:
1234 case Instruction::SUB_DOUBLE:
1235 case Instruction::SUB_DOUBLE_2ADDR:
1236 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1237 break;
1238
1239 case Instruction::MUL_FLOAT:
1240 case Instruction::MUL_FLOAT_2ADDR:
1241 case Instruction::MUL_DOUBLE:
1242 case Instruction::MUL_DOUBLE_2ADDR:
1243 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1244 break;
1245
1246 case Instruction::DIV_FLOAT:
1247 case Instruction::DIV_FLOAT_2ADDR:
1248 case Instruction::DIV_DOUBLE:
1249 case Instruction::DIV_DOUBLE_2ADDR:
1250 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1251 break;
1252
1253 case Instruction::REM_FLOAT:
1254 case Instruction::REM_FLOAT_2ADDR:
1255 case Instruction::REM_DOUBLE:
1256 case Instruction::REM_DOUBLE_2ADDR:
1257 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1258 break;
1259
buzbee6969d502012-06-15 16:40:31 -07001260 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001261 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1262 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001263 break;
1264 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001265 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1266 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001267 break;
1268
1269 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001270 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1271 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001272 break;
1273 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001274 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1275 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001276 break;
1277
1278 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001279 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1280 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001281 break;
1282 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001283 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1284 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001285 break;
1286
1287 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001288 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1289 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001290 break;
1291 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001292 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1293 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001294 break;
1295
1296 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001297 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1298 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001299 break;
1300 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001301 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1302 false /* NewFilledArray */);
1303 break;
1304 case Instruction::FILLED_NEW_ARRAY:
1305 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1306 true /* NewFilledArray */);
1307 break;
1308 case Instruction::FILLED_NEW_ARRAY_RANGE:
1309 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1310 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001311 break;
1312
1313 case Instruction::CONST_STRING:
1314 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001315 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1316 rlDest);
1317 break;
1318
1319 case Instruction::CONST_CLASS:
1320 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1321 rlDest);
1322 break;
1323
1324 case Instruction::CHECK_CAST:
1325 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001326 break;
1327
buzbee4f1181f2012-06-22 13:52:12 -07001328 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001329 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001330 break;
1331
buzbee32412962012-06-26 16:27:56 -07001332 case Instruction::MOVE_EXCEPTION:
1333 convertMoveException(cUnit, rlDest);
1334 break;
1335
1336 case Instruction::THROW:
1337 convertThrow(cUnit, rlSrc[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001338 /*
1339 * If this throw is standalone, terminate.
1340 * If it might rethrow, force termination
1341 * of the following block.
1342 */
1343 if (bb->fallThrough == NULL) {
1344 cUnit->irb->CreateUnreachable();
1345 } else {
1346 bb->fallThrough->fallThrough = NULL;
1347 bb->fallThrough->taken = NULL;
1348 }
buzbee32412962012-06-26 16:27:56 -07001349 break;
1350
buzbee2cfc6392012-05-07 14:51:40 -07001351 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001352 case Instruction::MOVE_RESULT:
1353 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001354 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001355 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001356 */
jeffhao9a4f0032012-08-30 16:17:40 -07001357 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001358 break;
1359
1360 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001361 convertMonitorEnterExit(cUnit, optFlags,
1362 greenland::IntrinsicHelper::MonitorEnter,
1363 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001364 break;
1365
1366 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001367 convertMonitorEnterExit(cUnit, optFlags,
1368 greenland::IntrinsicHelper::MonitorExit,
1369 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001370 break;
1371
1372 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001373 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001374 break;
1375
1376 case Instruction::NEW_ARRAY:
1377 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1378 break;
1379
1380 case Instruction::INSTANCE_OF:
1381 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1382 break;
1383
1384 case Instruction::AGET:
1385 if (rlDest.fp) {
1386 convertAget(cUnit, optFlags,
1387 greenland::IntrinsicHelper::HLArrayGetFloat,
1388 rlDest, rlSrc[0], rlSrc[1]);
1389 } else {
1390 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1391 rlDest, rlSrc[0], rlSrc[1]);
1392 }
1393 break;
1394 case Instruction::AGET_OBJECT:
1395 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1396 rlDest, rlSrc[0], rlSrc[1]);
1397 break;
1398 case Instruction::AGET_BOOLEAN:
1399 convertAget(cUnit, optFlags,
1400 greenland::IntrinsicHelper::HLArrayGetBoolean,
1401 rlDest, rlSrc[0], rlSrc[1]);
1402 break;
1403 case Instruction::AGET_BYTE:
1404 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1405 rlDest, rlSrc[0], rlSrc[1]);
1406 break;
1407 case Instruction::AGET_CHAR:
1408 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1409 rlDest, rlSrc[0], rlSrc[1]);
1410 break;
1411 case Instruction::AGET_SHORT:
1412 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1413 rlDest, rlSrc[0], rlSrc[1]);
1414 break;
1415 case Instruction::AGET_WIDE:
1416 if (rlDest.fp) {
1417 convertAget(cUnit, optFlags,
1418 greenland::IntrinsicHelper::HLArrayGetDouble,
1419 rlDest, rlSrc[0], rlSrc[1]);
1420 } else {
1421 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1422 rlDest, rlSrc[0], rlSrc[1]);
1423 }
1424 break;
1425
1426 case Instruction::APUT:
1427 if (rlSrc[0].fp) {
1428 convertAput(cUnit, optFlags,
1429 greenland::IntrinsicHelper::HLArrayPutFloat,
1430 rlSrc[0], rlSrc[1], rlSrc[2]);
1431 } else {
1432 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1433 rlSrc[0], rlSrc[1], rlSrc[2]);
1434 }
1435 break;
1436 case Instruction::APUT_OBJECT:
1437 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1438 rlSrc[0], rlSrc[1], rlSrc[2]);
1439 break;
1440 case Instruction::APUT_BOOLEAN:
1441 convertAput(cUnit, optFlags,
1442 greenland::IntrinsicHelper::HLArrayPutBoolean,
1443 rlSrc[0], rlSrc[1], rlSrc[2]);
1444 break;
1445 case Instruction::APUT_BYTE:
1446 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1447 rlSrc[0], rlSrc[1], rlSrc[2]);
1448 break;
1449 case Instruction::APUT_CHAR:
1450 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1451 rlSrc[0], rlSrc[1], rlSrc[2]);
1452 break;
1453 case Instruction::APUT_SHORT:
1454 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1455 rlSrc[0], rlSrc[1], rlSrc[2]);
1456 break;
1457 case Instruction::APUT_WIDE:
1458 if (rlSrc[0].fp) {
1459 convertAput(cUnit, optFlags,
1460 greenland::IntrinsicHelper::HLArrayPutDouble,
1461 rlSrc[0], rlSrc[1], rlSrc[2]);
1462 } else {
1463 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1464 rlSrc[0], rlSrc[1], rlSrc[2]);
1465 }
1466 break;
1467
buzbee101305f2012-06-28 18:00:56 -07001468 case Instruction::IGET:
1469 if (rlDest.fp) {
1470 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001471 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001472 } else {
1473 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001474 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001475 }
buzbee2cfc6392012-05-07 14:51:40 -07001476 break;
buzbee101305f2012-06-28 18:00:56 -07001477 case Instruction::IGET_OBJECT:
1478 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001479 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001480 break;
1481 case Instruction::IGET_BOOLEAN:
1482 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001483 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001484 break;
1485 case Instruction::IGET_BYTE:
1486 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001487 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001488 break;
1489 case Instruction::IGET_CHAR:
1490 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001491 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001492 break;
1493 case Instruction::IGET_SHORT:
1494 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001495 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001496 break;
1497 case Instruction::IGET_WIDE:
1498 if (rlDest.fp) {
1499 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001500 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001501 } else {
1502 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001503 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001504 }
1505 break;
1506 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001507 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001508 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1509 rlSrc[0], rlSrc[1], vC);
1510 } else {
1511 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1512 rlSrc[0], rlSrc[1], vC);
1513 }
1514 break;
1515 case Instruction::IPUT_OBJECT:
1516 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1517 rlSrc[0], rlSrc[1], vC);
1518 break;
1519 case Instruction::IPUT_BOOLEAN:
1520 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1521 rlSrc[0], rlSrc[1], vC);
1522 break;
1523 case Instruction::IPUT_BYTE:
1524 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1525 rlSrc[0], rlSrc[1], vC);
1526 break;
1527 case Instruction::IPUT_CHAR:
1528 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1529 rlSrc[0], rlSrc[1], vC);
1530 break;
1531 case Instruction::IPUT_SHORT:
1532 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1533 rlSrc[0], rlSrc[1], vC);
1534 break;
1535 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001536 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001537 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1538 rlSrc[0], rlSrc[1], vC);
1539 } else {
1540 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1541 rlSrc[0], rlSrc[1], vC);
1542 }
buzbee2cfc6392012-05-07 14:51:40 -07001543 break;
1544
1545 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001546 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001547 break;
1548
buzbee76592632012-06-29 15:18:35 -07001549 case Instruction::LONG_TO_INT:
1550 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1551 break;
1552
buzbee101305f2012-06-28 18:00:56 -07001553 case Instruction::INT_TO_LONG:
1554 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001555 break;
1556
buzbee101305f2012-06-28 18:00:56 -07001557 case Instruction::INT_TO_CHAR:
1558 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1559 greenland::IntrinsicHelper::IntToChar);
1560 break;
1561 case Instruction::INT_TO_BYTE:
1562 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1563 greenland::IntrinsicHelper::IntToByte);
1564 break;
1565 case Instruction::INT_TO_SHORT:
1566 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1567 greenland::IntrinsicHelper::IntToShort);
1568 break;
1569
buzbee76592632012-06-29 15:18:35 -07001570 case Instruction::INT_TO_FLOAT:
1571 case Instruction::LONG_TO_FLOAT:
1572 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001573 break;
1574
buzbee76592632012-06-29 15:18:35 -07001575 case Instruction::INT_TO_DOUBLE:
1576 case Instruction::LONG_TO_DOUBLE:
1577 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001578 break;
1579
buzbee76592632012-06-29 15:18:35 -07001580 case Instruction::FLOAT_TO_DOUBLE:
1581 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001582 break;
1583
buzbee76592632012-06-29 15:18:35 -07001584 case Instruction::DOUBLE_TO_FLOAT:
1585 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001586 break;
1587
1588 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001589 case Instruction::NEG_INT:
1590 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001591 break;
1592
1593 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001594 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001595 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001596 break;
1597
buzbee76592632012-06-29 15:18:35 -07001598 case Instruction::NOT_LONG:
1599 case Instruction::NOT_INT:
1600 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001601 break;
1602
buzbee2cfc6392012-05-07 14:51:40 -07001603 case Instruction::FLOAT_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001604 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2I, rlDest, rlSrc[0]);
1605 break;
1606
buzbee2cfc6392012-05-07 14:51:40 -07001607 case Instruction::DOUBLE_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001608 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2I, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001609 break;
1610
buzbee76592632012-06-29 15:18:35 -07001611 case Instruction::FLOAT_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001612 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2L, rlDest, rlSrc[0]);
1613 break;
1614
buzbee76592632012-06-29 15:18:35 -07001615 case Instruction::DOUBLE_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001616 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2L, rlDest, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001617 break;
1618
1619 case Instruction::CMPL_FLOAT:
1620 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1621 rlDest, rlSrc[0], rlSrc[1]);
1622 break;
1623 case Instruction::CMPG_FLOAT:
1624 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1625 rlDest, rlSrc[0], rlSrc[1]);
1626 break;
1627 case Instruction::CMPL_DOUBLE:
1628 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1629 rlDest, rlSrc[0], rlSrc[1]);
1630 break;
1631 case Instruction::CMPG_DOUBLE:
1632 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1633 rlDest, rlSrc[0], rlSrc[1]);
1634 break;
1635 case Instruction::CMP_LONG:
1636 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1637 rlDest, rlSrc[0], rlSrc[1]);
1638 break;
1639
buzbee76592632012-06-29 15:18:35 -07001640 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001641 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001642 break;
1643
1644 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001645 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001646 break;
buzbee2cfc6392012-05-07 14:51:40 -07001647
1648 default:
buzbee32412962012-06-26 16:27:56 -07001649 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001650 res = true;
1651 }
buzbeeb03f4872012-06-11 15:22:11 -07001652 if (objectDefinition) {
1653 setShadowFrameEntry(cUnit, (llvm::Value*)
1654 cUnit->llvmValues.elemList[rlDest.origSReg]);
1655 }
buzbee2cfc6392012-05-07 14:51:40 -07001656 return res;
1657}
1658
1659/* Extended MIR instructions like PHI */
1660void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1661 llvm::BasicBlock* llvmBB)
1662{
1663
1664 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1665 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001666 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001667 /*
1668 * The Art compiler's Phi nodes only handle 32-bit operands,
1669 * representing wide values using a matched set of Phi nodes
1670 * for the lower and upper halves. In the llvm world, we only
1671 * want a single Phi for wides. Here we will simply discard
1672 * the Phi node representing the high word.
1673 */
1674 if (rlDest.highWord) {
1675 return; // No Phi node - handled via low word
1676 }
1677 int* incoming = (int*)mir->dalvikInsn.vB;
buzbee2cfc6392012-05-07 14:51:40 -07001678 llvm::Type* phiType =
1679 llvmTypeFromLocRec(cUnit, rlDest);
1680 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1681 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1682 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001683 // Don't check width here.
1684 loc = oatGetRawSrc(cUnit, mir, i);
1685 DCHECK_EQ(rlDest.wide, loc.wide);
1686 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1687 DCHECK_EQ(rlDest.fp, loc.fp);
1688 DCHECK_EQ(rlDest.core, loc.core);
1689 DCHECK_EQ(rlDest.ref, loc.ref);
buzbeed1643e42012-09-05 14:06:51 -07001690 SafeMap<unsigned int, unsigned int>::iterator it;
1691 it = cUnit->blockIdMap.find(incoming[i]);
1692 DCHECK(it != cUnit->blockIdMap.end());
buzbee2cfc6392012-05-07 14:51:40 -07001693 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
buzbeed1643e42012-09-05 14:06:51 -07001694 getLLVMBlock(cUnit, it->second));
buzbee2cfc6392012-05-07 14:51:40 -07001695 }
1696 defineValue(cUnit, phi, rlDest.origSReg);
1697 break;
1698 }
1699 case kMirOpCopy: {
1700 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1701 break;
1702 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001703 case kMirOpNop:
1704 if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
1705 (bb->fallThrough == NULL)) {
1706 cUnit->irb->CreateUnreachable();
1707 }
1708 break;
1709
buzbee2cfc6392012-05-07 14:51:40 -07001710#if defined(TARGET_ARM)
1711 case kMirOpFusedCmplFloat:
1712 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1713 break;
1714 case kMirOpFusedCmpgFloat:
1715 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1716 break;
1717 case kMirOpFusedCmplDouble:
1718 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1719 break;
1720 case kMirOpFusedCmpgDouble:
1721 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1722 break;
1723 case kMirOpFusedCmpLong:
1724 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1725 break;
1726#endif
1727 default:
1728 break;
1729 }
1730}
1731
1732void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1733{
1734 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001735 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001736 arrayRef.push_back(cUnit->irb->getInt32(offset));
1737 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1738 cUnit->irb->SetDexOffset(node);
1739}
1740
1741// Attach method info as metadata to special intrinsic
1742void setMethodInfo(CompilationUnit* cUnit)
1743{
1744 // We don't want dex offset on this
1745 cUnit->irb->SetDexOffset(NULL);
1746 greenland::IntrinsicHelper::IntrinsicId id;
1747 id = greenland::IntrinsicHelper::MethodInfo;
1748 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1749 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1750 llvm::SmallVector<llvm::Value*, 2> regInfo;
1751 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1752 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1753 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1754 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1755 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1756 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1757 inst->setMetadata("RegInfo", regInfoNode);
1758 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1759 llvm::SmallVector<llvm::Value*, 50> pmap;
1760 for (int i = 0; i < promoSize; i++) {
1761 PromotionMap* p = &cUnit->promotionMap[i];
1762 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1763 ((p->fpReg & 0xff) << 16) |
1764 ((p->coreReg & 0xff) << 8) |
1765 ((p->fpLocation & 0xf) << 4) |
1766 (p->coreLocation & 0xf);
1767 pmap.push_back(cUnit->irb->getInt32(mapData));
1768 }
1769 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1770 inst->setMetadata("PromotionMap", mapNode);
1771 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1772}
1773
1774/* Handle the content in each basic block */
1775bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1776{
buzbeed1643e42012-09-05 14:06:51 -07001777 if (bb->blockType == kDead) return false;
buzbee2cfc6392012-05-07 14:51:40 -07001778 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
buzbeef5f5a122012-09-21 13:57:36 -07001779 if (llvmBB == NULL) {
1780 CHECK(bb->blockType == kExitBlock);
1781 } else {
1782 cUnit->irb->SetInsertPoint(llvmBB);
1783 setDexOffset(cUnit, bb->startOffset);
1784 }
buzbee2cfc6392012-05-07 14:51:40 -07001785
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001786 if (cUnit->printMe) {
1787 LOG(INFO) << "................................";
1788 LOG(INFO) << "Block id " << bb->id;
1789 if (llvmBB != NULL) {
1790 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1791 } else {
1792 LOG(INFO) << "llvmBB is NULL";
1793 }
1794 }
1795
buzbee2cfc6392012-05-07 14:51:40 -07001796 if (bb->blockType == kEntryBlock) {
1797 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001798 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1799 cUnit->numDalvikRegisters, true,
1800 kAllocMisc);
1801 for (int i = 0; i < cUnit->numSSARegs; i++) {
buzbee6ec5e232012-09-20 15:50:03 -07001802 int vReg = SRegToVReg(cUnit, i);
1803 if (vReg > SSA_METHOD_BASEREG) {
1804 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1805 }
buzbeeb03f4872012-06-11 15:22:11 -07001806 }
1807 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1808 if (canBeRef[i]) {
1809 cUnit->numShadowFrameEntries++;
1810 }
1811 }
1812 if (cUnit->numShadowFrameEntries > 0) {
1813 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1814 cUnit->numShadowFrameEntries, true,
1815 kAllocMisc);
1816 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1817 if (canBeRef[i]) {
1818 cUnit->shadowMap[j++] = i;
1819 }
1820 }
buzbeeb03f4872012-06-11 15:22:11 -07001821 }
Shih-wei Liao569daf12012-08-10 23:22:33 -07001822 greenland::IntrinsicHelper::IntrinsicId id =
1823 greenland::IntrinsicHelper::AllocaShadowFrame;
1824 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1825 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1826 cUnit->irb->CreateCall(func, entries);
buzbee2cfc6392012-05-07 14:51:40 -07001827 } else if (bb->blockType == kExitBlock) {
1828 /*
1829 * Because of the differences between how MIR/LIR and llvm handle exit
1830 * blocks, we won't explicitly covert them. On the llvm-to-lir
1831 * path, it will need to be regenereated.
1832 */
1833 return false;
buzbee6969d502012-06-15 16:40:31 -07001834 } else if (bb->blockType == kExceptionHandling) {
1835 /*
1836 * Because we're deferring null checking, delete the associated empty
1837 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001838 */
1839 llvmBB->eraseFromParent();
1840 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001841 }
1842
1843 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1844
1845 setDexOffset(cUnit, mir->offset);
1846
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001847 int opcode = mir->dalvikInsn.opcode;
1848 Instruction::Format dalvikFormat =
1849 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001850
1851 /* If we're compiling for the debugger, generate an update callout */
1852 if (cUnit->genDebugger) {
1853 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1854 //genDebuggerUpdate(cUnit, mir->offset);
1855 }
1856
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001857 if (opcode == kMirOpCheck) {
1858 // Combine check and work halves of throwing instruction.
1859 MIR* workHalf = mir->meta.throwInsn;
1860 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
1861 opcode = mir->dalvikInsn.opcode;
1862 SSARepresentation* ssaRep = workHalf->ssaRep;
1863 workHalf->ssaRep = mir->ssaRep;
1864 mir->ssaRep = ssaRep;
1865 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1866 if (bb->successorBlockList.blockListType == kCatch) {
1867 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
1868 greenland::IntrinsicHelper::CatchTargets);
1869 llvm::Value* switchKey =
1870 cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
1871 GrowableListIterator iter;
1872 oatGrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
1873 // New basic block to use for work half
1874 llvm::BasicBlock* workBB =
1875 llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
1876 llvm::SwitchInst* sw =
1877 cUnit->irb->CreateSwitch(switchKey, workBB,
1878 bb->successorBlockList.blocks.numUsed);
1879 while (true) {
1880 SuccessorBlockInfo *successorBlockInfo =
1881 (SuccessorBlockInfo *) oatGrowableListIteratorNext(&iter);
1882 if (successorBlockInfo == NULL) break;
1883 llvm::BasicBlock *target =
1884 getLLVMBlock(cUnit, successorBlockInfo->block->id);
1885 int typeIndex = successorBlockInfo->key;
1886 sw->addCase(cUnit->irb->getInt32(typeIndex), target);
1887 }
1888 llvmBB = workBB;
1889 cUnit->irb->SetInsertPoint(llvmBB);
1890 }
1891 }
1892
1893 if (opcode >= kMirOpFirst) {
buzbee2cfc6392012-05-07 14:51:40 -07001894 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1895 continue;
1896 }
1897
1898 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1899 NULL /* labelList */);
1900 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001901 Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001902 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001903 mir->offset, opcode,
buzbee2cfc6392012-05-07 14:51:40 -07001904 Instruction::Name(dalvikOpcode),
1905 dalvikFormat);
1906 }
1907 }
1908
buzbee4be777b2012-07-12 14:38:18 -07001909 if (bb->blockType == kEntryBlock) {
1910 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1911 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001912 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1913 }
1914
1915 return false;
1916}
1917
buzbee4f4dfc72012-07-02 14:54:44 -07001918char remapShorty(char shortyType) {
1919 /*
1920 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1921 * and longs/doubles are represented as a pair of registers. When sub-word
1922 * arguments (and method results) are passed, they are extended to Dalvik
1923 * virtual register containers. Because llvm is picky about type consistency,
1924 * we must either cast the "real" type to 32-bit container multiple Dalvik
1925 * register types, or always use the expanded values.
1926 * Here, we're doing the latter. We map the shorty signature to container
1927 * types (which is valid so long as we always do a real expansion of passed
1928 * arguments and field loads).
1929 */
1930 switch(shortyType) {
1931 case 'Z' : shortyType = 'I'; break;
1932 case 'B' : shortyType = 'I'; break;
1933 case 'S' : shortyType = 'I'; break;
1934 case 'C' : shortyType = 'I'; break;
1935 default: break;
1936 }
1937 return shortyType;
1938}
1939
buzbee2cfc6392012-05-07 14:51:40 -07001940llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1941
1942 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001943 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001944 greenland::kAccurate);
1945
1946 // Get argument type
1947 std::vector<llvm::Type*> args_type;
1948
1949 // method object
1950 args_type.push_back(cUnit->irb->GetJMethodTy());
1951
1952 // Do we have a "this"?
1953 if ((cUnit->access_flags & kAccStatic) == 0) {
1954 args_type.push_back(cUnit->irb->GetJObjectTy());
1955 }
1956
1957 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001958 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001959 greenland::kAccurate));
1960 }
1961
1962 return llvm::FunctionType::get(ret_type, args_type, false);
1963}
1964
1965bool createFunction(CompilationUnit* cUnit) {
1966 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1967 /* with_signature */ false));
1968 llvm::FunctionType* func_type = getFunctionType(cUnit);
1969
1970 if (func_type == NULL) {
1971 return false;
1972 }
1973
1974 cUnit->func = llvm::Function::Create(func_type,
1975 llvm::Function::ExternalLinkage,
1976 func_name, cUnit->module);
1977
1978 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1979 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1980
1981 arg_iter->setName("method");
1982 ++arg_iter;
1983
1984 int startSReg = cUnit->numRegs;
1985
1986 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1987 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1988 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1989 }
1990
1991 return true;
1992}
1993
1994bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1995{
1996 // Skip the exit block
buzbeed1643e42012-09-05 14:06:51 -07001997 if ((bb->blockType == kDead) ||(bb->blockType == kExitBlock)) {
buzbee2cfc6392012-05-07 14:51:40 -07001998 cUnit->idToBlockMap.Put(bb->id, NULL);
1999 } else {
2000 int offset = bb->startOffset;
2001 bool entryBlock = (bb->blockType == kEntryBlock);
2002 llvm::BasicBlock* llvmBB =
2003 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
buzbee8320f382012-09-11 16:29:42 -07002004 StringPrintf(kLabelFormat, bb->catchEntry ? kCatchBlock :
2005 kNormalBlock, offset, bb->id), cUnit->func);
buzbee2cfc6392012-05-07 14:51:40 -07002006 if (entryBlock) {
2007 cUnit->entryBB = llvmBB;
2008 cUnit->placeholderBB =
2009 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
2010 cUnit->func);
2011 }
2012 cUnit->idToBlockMap.Put(bb->id, llvmBB);
2013 }
2014 return false;
2015}
2016
2017
2018/*
2019 * Convert MIR to LLVM_IR
2020 * o For each ssa name, create LLVM named value. Type these
2021 * appropriately, and ignore high half of wide and double operands.
2022 * o For each MIR basic block, create an LLVM basic block.
2023 * o Iterate through the MIR a basic block at a time, setting arguments
2024 * to recovered ssa name.
2025 */
2026void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
2027{
2028 initIR(cUnit);
2029 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
2030
2031 // Create the function
2032 createFunction(cUnit);
2033
2034 // Create an LLVM basic block for each MIR block in dfs preorder
2035 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
2036 kPreOrderDFSTraversal, false /* isIterative */);
2037 /*
2038 * Create an llvm named value for each MIR SSA name. Note: we'll use
2039 * placeholders for all non-argument values (because we haven't seen
2040 * the definition yet).
2041 */
2042 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2043 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2044 arg_iter++; /* Skip path method */
2045 for (int i = 0; i < cUnit->numSSARegs; i++) {
2046 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07002047 RegLocation rlTemp = cUnit->regLocation[i];
2048 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07002049 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
2050 } else if ((i < cUnit->numRegs) ||
2051 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07002052 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
2053 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07002054 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
2055 val->setName(llvmSSAName(cUnit, i));
buzbee2cfc6392012-05-07 14:51:40 -07002056 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
buzbee2cfc6392012-05-07 14:51:40 -07002057 } else {
2058 // Recover previously-created argument values
2059 llvm::Value* argVal = arg_iter++;
2060 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
2061 }
2062 }
buzbee2cfc6392012-05-07 14:51:40 -07002063
2064 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
2065 kPreOrderDFSTraversal, false /* Iterative */);
2066
buzbee4be777b2012-07-12 14:38:18 -07002067 /*
2068 * In a few rare cases of verification failure, the verifier will
2069 * replace one or more Dalvik opcodes with the special
2070 * throw-verification-failure opcode. This can leave the SSA graph
2071 * in an invalid state, as definitions may be lost, while uses retained.
2072 * To work around this problem, we insert placeholder definitions for
2073 * all Dalvik SSA regs in the "placeholder" block. Here, after
2074 * bitcode conversion is complete, we examine those placeholder definitions
2075 * and delete any with no references (which normally is all of them).
2076 *
2077 * If any definitions remain, we link the placeholder block into the
2078 * CFG. Otherwise, it is deleted.
2079 */
2080 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
2081 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
2082 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2083 DCHECK(inst != NULL);
2084 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2085 DCHECK(val != NULL);
2086 if (val->getNumUses() == 0) {
2087 inst->eraseFromParent();
2088 }
2089 }
2090 setDexOffset(cUnit, 0);
2091 if (cUnit->placeholderBB->empty()) {
2092 cUnit->placeholderBB->eraseFromParent();
2093 } else {
2094 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2095 cUnit->irb->CreateBr(cUnit->entryTargetBB);
2096 cUnit->entryTargetBB = cUnit->placeholderBB;
2097 }
2098 cUnit->irb->SetInsertPoint(cUnit->entryBB);
2099 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07002100
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002101 if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
2102 if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
2103 LOG(INFO) << "Bitcode verification FAILED for "
2104 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
2105 << " of size " << cUnit->insnsSize;
2106 cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
2107 }
2108 }
buzbee2cfc6392012-05-07 14:51:40 -07002109
buzbeead8f15e2012-06-18 14:49:45 -07002110 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
2111 // Write bitcode to file
2112 std::string errmsg;
2113 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
2114 oatReplaceSpecialChars(fname);
2115 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07002116 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002117
buzbeead8f15e2012-06-18 14:49:45 -07002118 llvm::OwningPtr<llvm::tool_output_file> out_file(
2119 new llvm::tool_output_file(fname.c_str(), errmsg,
2120 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002121
buzbeead8f15e2012-06-18 14:49:45 -07002122 if (!errmsg.empty()) {
2123 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2124 }
2125
2126 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2127 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002128 }
buzbee2cfc6392012-05-07 14:51:40 -07002129}
2130
2131RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2132 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002133 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002134 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2135 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002136 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002137 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002138 // FIXME: need to be more robust, handle FP and be in a position to
2139 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002140 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2141 memset(&res, 0, sizeof(res));
2142 res.location = kLocPhysReg;
2143 res.lowReg = oatAllocTemp(cUnit);
2144 res.home = true;
2145 res.sRegLow = INVALID_SREG;
2146 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002147 llvm::Type* ty = val->getType();
2148 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2149 (ty == cUnit->irb->getDoubleTy()));
2150 if (res.wide) {
2151 res.highReg = oatAllocTemp(cUnit);
2152 }
buzbee4f1181f2012-06-22 13:52:12 -07002153 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002154 } else {
2155 DCHECK_EQ(valName[0], 'v');
2156 int baseSReg = INVALID_SREG;
2157 sscanf(valName.c_str(), "v%d_", &baseSReg);
2158 res = cUnit->regLocation[baseSReg];
2159 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002160 }
2161 } else {
2162 res = it->second;
2163 }
2164 return res;
2165}
2166
2167Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2168{
2169 Instruction::Code res = Instruction::NOP;
2170 if (isWide) {
2171 switch(op) {
2172 case kOpAdd: res = Instruction::ADD_LONG; break;
2173 case kOpSub: res = Instruction::SUB_LONG; break;
2174 case kOpMul: res = Instruction::MUL_LONG; break;
2175 case kOpDiv: res = Instruction::DIV_LONG; break;
2176 case kOpRem: res = Instruction::REM_LONG; break;
2177 case kOpAnd: res = Instruction::AND_LONG; break;
2178 case kOpOr: res = Instruction::OR_LONG; break;
2179 case kOpXor: res = Instruction::XOR_LONG; break;
2180 case kOpLsl: res = Instruction::SHL_LONG; break;
2181 case kOpLsr: res = Instruction::USHR_LONG; break;
2182 case kOpAsr: res = Instruction::SHR_LONG; break;
2183 default: LOG(FATAL) << "Unexpected OpKind " << op;
2184 }
2185 } else if (isConst){
2186 switch(op) {
2187 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2188 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2189 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2190 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2191 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2192 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2193 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2194 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2195 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2196 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2197 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2198 default: LOG(FATAL) << "Unexpected OpKind " << op;
2199 }
2200 } else {
2201 switch(op) {
2202 case kOpAdd: res = Instruction::ADD_INT; break;
2203 case kOpSub: res = Instruction::SUB_INT; break;
2204 case kOpMul: res = Instruction::MUL_INT; break;
2205 case kOpDiv: res = Instruction::DIV_INT; break;
2206 case kOpRem: res = Instruction::REM_INT; break;
2207 case kOpAnd: res = Instruction::AND_INT; break;
2208 case kOpOr: res = Instruction::OR_INT; break;
2209 case kOpXor: res = Instruction::XOR_INT; break;
2210 case kOpLsl: res = Instruction::SHL_INT; break;
2211 case kOpLsr: res = Instruction::USHR_INT; break;
2212 case kOpAsr: res = Instruction::SHR_INT; break;
2213 default: LOG(FATAL) << "Unexpected OpKind " << op;
2214 }
2215 }
2216 return res;
2217}
2218
buzbee4f1181f2012-06-22 13:52:12 -07002219Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2220{
2221 Instruction::Code res = Instruction::NOP;
2222 if (isWide) {
2223 switch(op) {
2224 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2225 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2226 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2227 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2228 case kOpRem: res = Instruction::REM_DOUBLE; break;
2229 default: LOG(FATAL) << "Unexpected OpKind " << op;
2230 }
2231 } else {
2232 switch(op) {
2233 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2234 case kOpSub: res = Instruction::SUB_FLOAT; break;
2235 case kOpMul: res = Instruction::MUL_FLOAT; break;
2236 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2237 case kOpRem: res = Instruction::REM_FLOAT; break;
2238 default: LOG(FATAL) << "Unexpected OpKind " << op;
2239 }
2240 }
2241 return res;
2242}
2243
2244void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2245{
2246 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002247 /*
2248 * Normally, we won't ever generate an FP operation with an immediate
2249 * operand (not supported in Dex instruction set). However, the IR builder
2250 * may insert them - in particular for createNegFP. Recognize this case
2251 * and deal with it.
2252 */
2253 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2254 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2255 DCHECK(op2C == NULL);
2256 if ((op1C != NULL) && (op == kOpSub)) {
2257 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2258 if (rlDest.wide) {
2259 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2260 } else {
2261 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2262 }
buzbee4f1181f2012-06-22 13:52:12 -07002263 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002264 DCHECK(op1C == NULL);
2265 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2266 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2267 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2268 if (rlDest.wide) {
2269 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2270 } else {
2271 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2272 }
buzbee4f1181f2012-06-22 13:52:12 -07002273 }
2274}
2275
buzbee101305f2012-06-28 18:00:56 -07002276void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2277 Instruction::Code opcode)
2278{
2279 RegLocation rlDest = getLoc(cUnit, inst);
2280 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2281 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2282}
2283
buzbee76592632012-06-29 15:18:35 -07002284void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2285{
2286 RegLocation rlDest = getLoc(cUnit, inst);
2287 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2288 Instruction::Code opcode;
2289 if (rlDest.wide) {
2290 if (rlSrc.wide) {
2291 opcode = Instruction::LONG_TO_DOUBLE;
2292 } else {
2293 opcode = Instruction::INT_TO_DOUBLE;
2294 }
2295 } else {
2296 if (rlSrc.wide) {
2297 opcode = Instruction::LONG_TO_FLOAT;
2298 } else {
2299 opcode = Instruction::INT_TO_FLOAT;
2300 }
2301 }
2302 genConversion(cUnit, opcode, rlDest, rlSrc);
2303}
2304
TDYa1274ec8ccd2012-08-11 07:04:57 -07002305void cvtFPToInt(CompilationUnit* cUnit, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002306{
TDYa1274ec8ccd2012-08-11 07:04:57 -07002307 RegLocation rlDest = getLoc(cUnit, call_inst);
2308 RegLocation rlSrc = getLoc(cUnit, call_inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002309 Instruction::Code opcode;
2310 if (rlDest.wide) {
2311 if (rlSrc.wide) {
2312 opcode = Instruction::DOUBLE_TO_LONG;
2313 } else {
2314 opcode = Instruction::FLOAT_TO_LONG;
2315 }
2316 } else {
2317 if (rlSrc.wide) {
2318 opcode = Instruction::DOUBLE_TO_INT;
2319 } else {
2320 opcode = Instruction::FLOAT_TO_INT;
2321 }
2322 }
2323 genConversion(cUnit, opcode, rlDest, rlSrc);
2324}
2325
2326void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2327{
2328 RegLocation rlDest = getLoc(cUnit, inst);
2329 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2330 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2331}
2332
2333void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2334{
2335 RegLocation rlDest = getLoc(cUnit, inst);
2336 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2337 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2338 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2339 storeValue(cUnit, rlDest, rlSrc);
2340}
2341
2342void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2343{
2344 RegLocation rlDest = getLoc(cUnit, inst);
2345 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2346 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2347}
2348
2349
buzbee101305f2012-06-28 18:00:56 -07002350void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2351{
2352 // TODO: evaluate src/tgt types and add general support for more than int to long
2353 RegLocation rlDest = getLoc(cUnit, inst);
2354 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2355 DCHECK(rlDest.wide);
2356 DCHECK(!rlSrc.wide);
2357 DCHECK(!rlDest.fp);
2358 DCHECK(!rlSrc.fp);
2359 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2360 if (rlSrc.location == kLocPhysReg) {
2361 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2362 } else {
2363 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2364 }
2365 if (isSigned) {
2366 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2367 } else {
2368 loadConstant(cUnit, rlResult.highReg, 0);
2369 }
2370 storeValueWide(cUnit, rlDest, rlResult);
2371}
2372
buzbee2cfc6392012-05-07 14:51:40 -07002373void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2374{
2375 RegLocation rlDest = getLoc(cUnit, inst);
2376 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002377 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002378 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2379 if ((op == kOpSub) && (lhsImm != NULL)) {
2380 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002381 if (rlSrc1.wide) {
2382 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2383 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2384 } else {
2385 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2386 lhsImm->getSExtValue());
2387 }
buzbee4f1181f2012-06-22 13:52:12 -07002388 return;
2389 }
2390 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002391 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2392 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002393 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2394 if (!rlDest.wide && (constRhs != NULL)) {
buzbee2cfc6392012-05-07 14:51:40 -07002395 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
buzbee9a2487f2012-07-26 14:01:13 -07002396 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002397 } else {
2398 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002399 RegLocation rlSrc2;
2400 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002401 // ir_builder converts NOT_LONG to xor src, -1. Restore
2402 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2403 DCHECK_EQ(-1L, constRhs->getSExtValue());
2404 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002405 rlSrc2 = rlSrc1;
2406 } else {
2407 rlSrc2 = getLoc(cUnit, rhs);
2408 }
buzbee2cfc6392012-05-07 14:51:40 -07002409 if (rlDest.wide) {
2410 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2411 } else {
2412 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2413 }
2414 }
2415}
2416
buzbee2a83e8f2012-07-13 16:42:30 -07002417void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2418 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002419{
buzbee2a83e8f2012-07-13 16:42:30 -07002420 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2421 RegLocation rlDest = getLoc(cUnit, callInst);
2422 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2423 llvm::Value* rhs = callInst->getArgOperand(1);
2424 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2425 DCHECK(!rlDest.wide);
2426 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002427 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002428 RegLocation rlShift = getLoc(cUnit, rhs);
2429 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2430 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2431 } else {
2432 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2433 }
buzbee101305f2012-06-28 18:00:56 -07002434 }
2435}
2436
buzbee2cfc6392012-05-07 14:51:40 -07002437void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2438{
2439 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2440 DCHECK(brInst != NULL);
2441 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2442 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2443 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2444}
2445
2446void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2447{
2448 // Nop - these have already been processed
2449}
2450
2451void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2452{
2453 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2454 llvm::Value* retVal = retInst->getReturnValue();
2455 if (retVal != NULL) {
2456 RegLocation rlSrc = getLoc(cUnit, retVal);
2457 if (rlSrc.wide) {
2458 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2459 } else {
2460 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2461 }
2462 }
2463 genExitSequence(cUnit);
2464}
2465
2466ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2467{
2468 ConditionCode res = kCondAl;
2469 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002470 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002471 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2472 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2473 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002474 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002475 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002476 default: LOG(FATAL) << "Unexpected llvm condition";
2477 }
2478 return res;
2479}
2480
2481void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2482{
2483 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2484 UNIMPLEMENTED(FATAL);
2485}
2486
2487void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2488 llvm::BranchInst* brInst)
2489{
2490 // Get targets
2491 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2492 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2493 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2494 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2495 // Get comparison operands
2496 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2497 ConditionCode cond = getCond(iCmpInst->getPredicate());
2498 llvm::Value* lhs = iCmpInst->getOperand(0);
2499 // Not expecting a constant as 1st operand
2500 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2501 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2502 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2503 llvm::Value* rhs = inst->getOperand(1);
2504#if defined(TARGET_MIPS)
2505 // Compare and branch in one shot
2506 (void)taken;
2507 (void)cond;
2508 (void)rhs;
2509 UNIMPLEMENTED(FATAL);
2510#else
2511 //Compare, then branch
2512 // TODO: handle fused CMP_LONG/IF_xxZ case
2513 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2514 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002515 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2516 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002517 } else {
2518 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2519 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2520 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2521 }
2522 opCondBranch(cUnit, cond, taken);
2523#endif
2524 // Fallthrough
2525 opUnconditionalBranch(cUnit, fallThrough);
2526}
2527
2528void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2529 llvm::Function* callee)
2530{
2531 UNIMPLEMENTED(FATAL);
2532}
2533
buzbee2cfc6392012-05-07 14:51:40 -07002534void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2535{
buzbee4f1181f2012-06-22 13:52:12 -07002536 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002537 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2538 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002539 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2540 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002541 if (rlSrc.wide) {
2542 storeValueWide(cUnit, rlDest, rlSrc);
2543 } else {
2544 storeValue(cUnit, rlDest, rlSrc);
2545 }
2546}
2547
2548// Note: Immediate arg is a ConstantInt regardless of result type
2549void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2550{
buzbee4f1181f2012-06-22 13:52:12 -07002551 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002552 llvm::ConstantInt* src =
2553 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2554 uint64_t immval = src->getZExtValue();
2555 RegLocation rlDest = getLoc(cUnit, callInst);
2556 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2557 if (rlDest.wide) {
2558 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2559 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2560 storeValueWide(cUnit, rlDest, rlResult);
2561 } else {
2562 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2563 storeValue(cUnit, rlDest, rlResult);
2564 }
2565}
2566
buzbee101305f2012-06-28 18:00:56 -07002567void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2568 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002569{
buzbee4f1181f2012-06-22 13:52:12 -07002570 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002571 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002572 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002573 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002574 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002575 if (isString) {
2576 genConstString(cUnit, index, rlDest);
2577 } else {
2578 genConstClass(cUnit, index, rlDest);
2579 }
2580}
2581
2582void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2583{
2584 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2585 llvm::ConstantInt* offsetVal =
2586 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2587 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2588 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002589}
2590
buzbee4f1181f2012-06-22 13:52:12 -07002591void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2592{
buzbee32412962012-06-26 16:27:56 -07002593 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002594 llvm::ConstantInt* typeIdxVal =
2595 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2596 uint32_t typeIdx = typeIdxVal->getZExtValue();
2597 RegLocation rlDest = getLoc(cUnit, callInst);
2598 genNewInstance(cUnit, typeIdx, rlDest);
2599}
2600
buzbee8fa0fda2012-06-27 15:44:52 -07002601void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2602{
2603 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2604 llvm::ConstantInt* typeIdxVal =
2605 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2606 uint32_t typeIdx = typeIdxVal->getZExtValue();
2607 llvm::Value* len = callInst->getArgOperand(1);
2608 RegLocation rlLen = getLoc(cUnit, len);
2609 RegLocation rlDest = getLoc(cUnit, callInst);
2610 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2611}
2612
2613void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2614{
2615 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2616 llvm::ConstantInt* typeIdxVal =
2617 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2618 uint32_t typeIdx = typeIdxVal->getZExtValue();
2619 llvm::Value* src = callInst->getArgOperand(1);
2620 RegLocation rlSrc = getLoc(cUnit, src);
2621 RegLocation rlDest = getLoc(cUnit, callInst);
2622 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2623}
2624
buzbee32412962012-06-26 16:27:56 -07002625void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2626{
2627 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2628 llvm::Value* src = callInst->getArgOperand(0);
2629 RegLocation rlSrc = getLoc(cUnit, src);
2630 genThrow(cUnit, rlSrc);
2631}
2632
buzbee8fa0fda2012-06-27 15:44:52 -07002633void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2634 llvm::CallInst* callInst)
2635{
2636 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2637 llvm::ConstantInt* optFlags =
2638 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2639 llvm::Value* src = callInst->getArgOperand(1);
2640 RegLocation rlSrc = getLoc(cUnit, src);
2641 if (isEnter) {
2642 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2643 } else {
2644 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2645 }
2646}
2647
buzbee76592632012-06-29 15:18:35 -07002648void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002649{
2650 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2651 llvm::ConstantInt* optFlags =
2652 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2653 llvm::Value* src = callInst->getArgOperand(1);
2654 RegLocation rlSrc = getLoc(cUnit, src);
2655 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2656 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2657 RegLocation rlDest = getLoc(cUnit, callInst);
2658 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2659 int lenOffset = Array::LengthOffset().Int32Value();
2660 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2661 storeValue(cUnit, rlDest, rlResult);
2662}
2663
buzbee32412962012-06-26 16:27:56 -07002664void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2665{
buzbee32412962012-06-26 16:27:56 -07002666 RegLocation rlDest = getLoc(cUnit, callInst);
Ian Rogers474b6da2012-09-25 00:20:38 -07002667 genMoveException(cUnit, rlDest);
buzbee32412962012-06-26 16:27:56 -07002668}
2669
buzbee4f1181f2012-06-22 13:52:12 -07002670void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2671 bool isObject)
2672{
buzbee32412962012-06-26 16:27:56 -07002673 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002674 llvm::ConstantInt* typeIdxVal =
2675 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2676 uint32_t typeIdx = typeIdxVal->getZExtValue();
2677 RegLocation rlDest = getLoc(cUnit, callInst);
2678 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2679}
2680
buzbee8fa0fda2012-06-27 15:44:52 -07002681void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2682 bool isObject)
2683{
2684 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2685 llvm::ConstantInt* typeIdxVal =
2686 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2687 uint32_t typeIdx = typeIdxVal->getZExtValue();
2688 llvm::Value* src = callInst->getArgOperand(1);
2689 RegLocation rlSrc = getLoc(cUnit, src);
2690 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2691}
2692
2693void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2694 int scale)
2695{
2696 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2697 llvm::ConstantInt* optFlags =
2698 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2699 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2700 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2701 RegLocation rlDest = getLoc(cUnit, callInst);
2702 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2703 rlDest, scale);
2704}
2705
2706void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002707 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002708{
2709 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2710 llvm::ConstantInt* optFlags =
2711 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2712 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2713 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2714 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002715 if (isObject) {
2716 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2717 rlSrc, scale);
2718 } else {
2719 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2720 rlSrc, scale);
2721 }
2722}
2723
2724void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2725{
2726 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2727}
2728
2729void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2730 OpSize size, int scale)
2731{
2732 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002733}
2734
buzbee101305f2012-06-28 18:00:56 -07002735void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2736 bool isWide, bool isObj)
2737{
2738 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2739 llvm::ConstantInt* optFlags =
2740 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2741 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2742 llvm::ConstantInt* fieldIdx =
2743 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2744 RegLocation rlDest = getLoc(cUnit, callInst);
2745 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2746 size, rlDest, rlObj, isWide, isObj);
2747}
2748
2749void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2750 bool isWide, bool isObj)
2751{
2752 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2753 llvm::ConstantInt* optFlags =
2754 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2755 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2756 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2757 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002758 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002759 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2760 size, rlSrc, rlObj, isWide, isObj);
2761}
2762
2763void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2764{
2765 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2766 llvm::ConstantInt* typeIdx =
2767 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2768 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2769 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2770}
2771
buzbee76592632012-06-29 15:18:35 -07002772void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2773 Instruction::Code opcode)
2774{
2775 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2776 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2777 RegLocation rlDest = getLoc(cUnit, callInst);
2778 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2779}
2780
2781void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2782{
2783 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2784 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2785 RegLocation rlDest = getLoc(cUnit, callInst);
2786 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2787}
2788
buzbeef58c12c2012-07-03 15:06:29 -07002789void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2790{
2791 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2792 DCHECK(swInst != NULL);
2793 llvm::Value* testVal = swInst->getCondition();
2794 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2795 DCHECK(tableOffsetNode != NULL);
2796 llvm::ConstantInt* tableOffsetValue =
2797 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2798 int32_t tableOffset = tableOffsetValue->getSExtValue();
2799 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeea1da8a52012-07-09 14:00:21 -07002800 const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2801 u2 tableMagic = *table;
2802 if (tableMagic == 0x100) {
2803 genPackedSwitch(cUnit, tableOffset, rlSrc);
2804 } else {
2805 DCHECK_EQ(tableMagic, 0x200);
2806 genSparseSwitch(cUnit, tableOffset, rlSrc);
2807 }
buzbeef58c12c2012-07-03 15:06:29 -07002808}
2809
buzbee6969d502012-06-15 16:40:31 -07002810void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002811 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002812{
2813 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2814 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002815 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002816 info->result.location = kLocInvalid;
2817 } else {
2818 info->result = getLoc(cUnit, callInst);
2819 }
2820 llvm::ConstantInt* invokeTypeVal =
2821 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2822 llvm::ConstantInt* methodIndexVal =
2823 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2824 llvm::ConstantInt* optFlagsVal =
2825 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2826 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2827 info->index = methodIndexVal->getZExtValue();
2828 info->optFlags = optFlagsVal->getZExtValue();
2829 info->offset = cUnit->currentDalvikOffset;
2830
buzbee6969d502012-06-15 16:40:31 -07002831 // Count the argument words, and then build argument array.
2832 info->numArgWords = 0;
2833 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2834 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2835 info->numArgWords += tLoc.wide ? 2 : 1;
2836 }
2837 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2838 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2839 // Now, fill in the location records, synthesizing high loc of wide vals
2840 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002841 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002842 if (info->args[next].wide) {
2843 next++;
2844 // TODO: Might make sense to mark this as an invalid loc
2845 info->args[next].origSReg = info->args[next-1].origSReg+1;
2846 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2847 }
2848 next++;
2849 }
buzbee4f4dfc72012-07-02 14:54:44 -07002850 // TODO - rework such that we no longer need isRange
2851 info->isRange = (info->numArgWords > 5);
2852
buzbee76592632012-06-29 15:18:35 -07002853 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002854 genFilledNewArray(cUnit, info);
2855 } else {
2856 genInvoke(cUnit, info);
2857 }
buzbee6969d502012-06-15 16:40:31 -07002858}
2859
buzbeead8f15e2012-06-18 14:49:45 -07002860/* Look up the RegLocation associated with a Value. Must already be defined */
2861RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2862{
2863 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2864 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2865 return it->second;
2866}
2867
buzbee2cfc6392012-05-07 14:51:40 -07002868bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2869{
buzbee0967a252012-09-14 10:43:54 -07002870 while (cUnit->llvmBlocks.find(bb) == cUnit->llvmBlocks.end()) {
2871 llvm::BasicBlock* nextBB = NULL;
2872 cUnit->llvmBlocks.insert(bb);
2873 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2874 // Define the starting label
2875 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2876 // Extract the type and starting offset from the block's name
2877 char blockType = kNormalBlock;
2878 if (!isEntry) {
2879 const char* blockName = bb->getName().str().c_str();
2880 int dummy;
2881 sscanf(blockName, kLabelFormat, &blockType, &blockLabel->operands[0], &dummy);
2882 cUnit->currentDalvikOffset = blockLabel->operands[0];
2883 } else {
2884 cUnit->currentDalvikOffset = 0;
2885 }
2886 // Set the label kind
2887 blockLabel->opcode = kPseudoNormalBlockLabel;
2888 // Insert the label
2889 oatAppendLIR(cUnit, blockLabel);
buzbee2cfc6392012-05-07 14:51:40 -07002890
buzbee0967a252012-09-14 10:43:54 -07002891 LIR* headLIR = NULL;
buzbee8320f382012-09-11 16:29:42 -07002892
buzbee0967a252012-09-14 10:43:54 -07002893 if (blockType == kCatchBlock) {
2894 headLIR = newLIR0(cUnit, kPseudoSafepointPC);
2895 }
buzbee8320f382012-09-11 16:29:42 -07002896
buzbee0967a252012-09-14 10:43:54 -07002897 // Free temp registers and reset redundant store tracking */
2898 oatResetRegPool(cUnit);
2899 oatResetDefTracking(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002900
buzbee0967a252012-09-14 10:43:54 -07002901 //TODO: restore oat incoming liveness optimization
2902 oatClobberAllRegs(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002903
buzbee0967a252012-09-14 10:43:54 -07002904 if (isEntry) {
2905 RegLocation* argLocs = (RegLocation*)
2906 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2907 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2908 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2909 // Skip past Method*
2910 it++;
2911 for (unsigned i = 0; it != it_end; ++it) {
2912 llvm::Value* val = it;
2913 argLocs[i++] = valToLoc(cUnit, val);
2914 llvm::Type* ty = val->getType();
2915 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2916 argLocs[i] = argLocs[i-1];
2917 argLocs[i].lowReg = argLocs[i].highReg;
2918 argLocs[i].origSReg++;
2919 argLocs[i].sRegLow = INVALID_SREG;
2920 argLocs[i].highWord = true;
2921 i++;
2922 }
2923 }
2924 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
2925 }
2926
2927 // Visit all of the instructions in the block
2928 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2929 llvm::Instruction* inst = it;
2930 llvm::BasicBlock::iterator nextIt = ++it;
2931 // Extract the Dalvik offset from the instruction
2932 uint32_t opcode = inst->getOpcode();
2933 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2934 if (dexOffsetNode != NULL) {
2935 llvm::ConstantInt* dexOffsetValue =
2936 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2937 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2938 }
2939
2940 oatResetRegPool(cUnit);
2941 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2942 oatClobberAllRegs(cUnit);
2943 }
2944
2945 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2946 oatResetDefTracking(cUnit);
2947 }
2948
2949 #ifndef NDEBUG
2950 /* Reset temp tracking sanity check */
2951 cUnit->liveSReg = INVALID_SREG;
2952 #endif
2953
2954 // TODO: use llvm opcode name here instead of "boundary" if verbose
2955 LIR* boundaryLIR = markBoundary(cUnit, cUnit->currentDalvikOffset, "boundary");
2956
2957 /* Remember the first LIR for thisl block*/
2958 if (headLIR == NULL) {
2959 headLIR = boundaryLIR;
2960 headLIR->defMask = ENCODE_ALL;
2961 }
2962
2963 switch(opcode) {
2964
2965 case llvm::Instruction::ICmp: {
2966 llvm::Instruction* nextInst = nextIt;
2967 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2968 if (brInst != NULL /* and... */) {
2969 cvtICmpBr(cUnit, inst, brInst);
2970 ++it;
2971 } else {
2972 cvtICmp(cUnit, inst);
2973 }
2974 }
2975 break;
2976
2977 case llvm::Instruction::Call: {
2978 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2979 llvm::Function* callee = callInst->getCalledFunction();
2980 greenland::IntrinsicHelper::IntrinsicId id =
2981 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2982 switch (id) {
2983 case greenland::IntrinsicHelper::AllocaShadowFrame:
2984 case greenland::IntrinsicHelper::SetShadowFrameEntry:
2985 case greenland::IntrinsicHelper::PopShadowFrame:
2986 // Ignore shadow frame stuff for quick compiler
2987 break;
2988 case greenland::IntrinsicHelper::CopyInt:
2989 case greenland::IntrinsicHelper::CopyObj:
2990 case greenland::IntrinsicHelper::CopyFloat:
2991 case greenland::IntrinsicHelper::CopyLong:
2992 case greenland::IntrinsicHelper::CopyDouble:
2993 cvtCopy(cUnit, callInst);
2994 break;
2995 case greenland::IntrinsicHelper::ConstInt:
2996 case greenland::IntrinsicHelper::ConstObj:
2997 case greenland::IntrinsicHelper::ConstLong:
2998 case greenland::IntrinsicHelper::ConstFloat:
2999 case greenland::IntrinsicHelper::ConstDouble:
3000 cvtConst(cUnit, callInst);
3001 break;
3002 case greenland::IntrinsicHelper::DivInt:
3003 case greenland::IntrinsicHelper::DivLong:
3004 cvtBinOp(cUnit, kOpDiv, inst);
3005 break;
3006 case greenland::IntrinsicHelper::RemInt:
3007 case greenland::IntrinsicHelper::RemLong:
3008 cvtBinOp(cUnit, kOpRem, inst);
3009 break;
3010 case greenland::IntrinsicHelper::MethodInfo:
3011 // Already dealt with - just ignore it here.
3012 break;
3013 case greenland::IntrinsicHelper::CheckSuspend:
3014 genSuspendTest(cUnit, 0 /* optFlags already applied */);
3015 break;
3016 case greenland::IntrinsicHelper::HLInvokeObj:
3017 case greenland::IntrinsicHelper::HLInvokeFloat:
3018 case greenland::IntrinsicHelper::HLInvokeDouble:
3019 case greenland::IntrinsicHelper::HLInvokeLong:
3020 case greenland::IntrinsicHelper::HLInvokeInt:
3021 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
3022 break;
3023 case greenland::IntrinsicHelper::HLInvokeVoid:
3024 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
3025 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003026 case greenland::IntrinsicHelper::HLFilledNewArray:
buzbee0967a252012-09-14 10:43:54 -07003027 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
3028 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003029 case greenland::IntrinsicHelper::HLFillArrayData:
buzbee0967a252012-09-14 10:43:54 -07003030 cvtFillArrayData(cUnit, callInst);
3031 break;
3032 case greenland::IntrinsicHelper::ConstString:
3033 cvtConstObject(cUnit, callInst, true /* isString */);
3034 break;
3035 case greenland::IntrinsicHelper::ConstClass:
3036 cvtConstObject(cUnit, callInst, false /* isString */);
3037 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003038 case greenland::IntrinsicHelper::HLCheckCast:
buzbee0967a252012-09-14 10:43:54 -07003039 cvtCheckCast(cUnit, callInst);
3040 break;
3041 case greenland::IntrinsicHelper::NewInstance:
3042 cvtNewInstance(cUnit, callInst);
3043 break;
3044 case greenland::IntrinsicHelper::HLSgetObject:
3045 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
3046 break;
3047 case greenland::IntrinsicHelper::HLSget:
3048 case greenland::IntrinsicHelper::HLSgetFloat:
3049 case greenland::IntrinsicHelper::HLSgetBoolean:
3050 case greenland::IntrinsicHelper::HLSgetByte:
3051 case greenland::IntrinsicHelper::HLSgetChar:
3052 case greenland::IntrinsicHelper::HLSgetShort:
3053 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
3054 break;
3055 case greenland::IntrinsicHelper::HLSgetWide:
3056 case greenland::IntrinsicHelper::HLSgetDouble:
3057 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
3058 break;
3059 case greenland::IntrinsicHelper::HLSput:
3060 case greenland::IntrinsicHelper::HLSputFloat:
3061 case greenland::IntrinsicHelper::HLSputBoolean:
3062 case greenland::IntrinsicHelper::HLSputByte:
3063 case greenland::IntrinsicHelper::HLSputChar:
3064 case greenland::IntrinsicHelper::HLSputShort:
3065 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
3066 break;
3067 case greenland::IntrinsicHelper::HLSputWide:
3068 case greenland::IntrinsicHelper::HLSputDouble:
3069 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
3070 break;
3071 case greenland::IntrinsicHelper::HLSputObject:
3072 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
3073 break;
3074 case greenland::IntrinsicHelper::GetException:
3075 cvtMoveException(cUnit, callInst);
3076 break;
TDYa127f71bf5a2012-07-29 20:09:52 -07003077 case greenland::IntrinsicHelper::HLThrowException:
buzbee0967a252012-09-14 10:43:54 -07003078 cvtThrow(cUnit, callInst);
3079 break;
3080 case greenland::IntrinsicHelper::MonitorEnter:
3081 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
3082 break;
3083 case greenland::IntrinsicHelper::MonitorExit:
3084 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
3085 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003086 case greenland::IntrinsicHelper::OptArrayLength:
buzbee0967a252012-09-14 10:43:54 -07003087 cvtArrayLength(cUnit, callInst);
3088 break;
3089 case greenland::IntrinsicHelper::NewArray:
3090 cvtNewArray(cUnit, callInst);
3091 break;
3092 case greenland::IntrinsicHelper::InstanceOf:
3093 cvtInstanceOf(cUnit, callInst);
3094 break;
3095
3096 case greenland::IntrinsicHelper::HLArrayGet:
3097 case greenland::IntrinsicHelper::HLArrayGetObject:
3098 case greenland::IntrinsicHelper::HLArrayGetFloat:
3099 cvtAget(cUnit, callInst, kWord, 2);
3100 break;
3101 case greenland::IntrinsicHelper::HLArrayGetWide:
3102 case greenland::IntrinsicHelper::HLArrayGetDouble:
3103 cvtAget(cUnit, callInst, kLong, 3);
3104 break;
3105 case greenland::IntrinsicHelper::HLArrayGetBoolean:
3106 cvtAget(cUnit, callInst, kUnsignedByte, 0);
3107 break;
3108 case greenland::IntrinsicHelper::HLArrayGetByte:
3109 cvtAget(cUnit, callInst, kSignedByte, 0);
3110 break;
3111 case greenland::IntrinsicHelper::HLArrayGetChar:
3112 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
3113 break;
3114 case greenland::IntrinsicHelper::HLArrayGetShort:
3115 cvtAget(cUnit, callInst, kSignedHalf, 1);
3116 break;
3117
3118 case greenland::IntrinsicHelper::HLArrayPut:
3119 case greenland::IntrinsicHelper::HLArrayPutFloat:
3120 cvtAputPrimitive(cUnit, callInst, kWord, 2);
3121 break;
3122 case greenland::IntrinsicHelper::HLArrayPutObject:
3123 cvtAputObj(cUnit, callInst);
3124 break;
3125 case greenland::IntrinsicHelper::HLArrayPutWide:
3126 case greenland::IntrinsicHelper::HLArrayPutDouble:
3127 cvtAputPrimitive(cUnit, callInst, kLong, 3);
3128 break;
3129 case greenland::IntrinsicHelper::HLArrayPutBoolean:
3130 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
3131 break;
3132 case greenland::IntrinsicHelper::HLArrayPutByte:
3133 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
3134 break;
3135 case greenland::IntrinsicHelper::HLArrayPutChar:
3136 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
3137 break;
3138 case greenland::IntrinsicHelper::HLArrayPutShort:
3139 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
3140 break;
3141
3142 case greenland::IntrinsicHelper::HLIGet:
3143 case greenland::IntrinsicHelper::HLIGetFloat:
3144 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3145 break;
3146 case greenland::IntrinsicHelper::HLIGetObject:
3147 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3148 break;
3149 case greenland::IntrinsicHelper::HLIGetWide:
3150 case greenland::IntrinsicHelper::HLIGetDouble:
3151 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3152 break;
3153 case greenland::IntrinsicHelper::HLIGetBoolean:
3154 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3155 false /* obj */);
3156 break;
3157 case greenland::IntrinsicHelper::HLIGetByte:
3158 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3159 false /* obj */);
3160 break;
3161 case greenland::IntrinsicHelper::HLIGetChar:
3162 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3163 false /* obj */);
3164 break;
3165 case greenland::IntrinsicHelper::HLIGetShort:
3166 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3167 false /* obj */);
3168 break;
3169
3170 case greenland::IntrinsicHelper::HLIPut:
3171 case greenland::IntrinsicHelper::HLIPutFloat:
3172 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3173 break;
3174 case greenland::IntrinsicHelper::HLIPutObject:
3175 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3176 break;
3177 case greenland::IntrinsicHelper::HLIPutWide:
3178 case greenland::IntrinsicHelper::HLIPutDouble:
3179 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3180 break;
3181 case greenland::IntrinsicHelper::HLIPutBoolean:
3182 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3183 false /* obj */);
3184 break;
3185 case greenland::IntrinsicHelper::HLIPutByte:
3186 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3187 false /* obj */);
3188 break;
3189 case greenland::IntrinsicHelper::HLIPutChar:
3190 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3191 false /* obj */);
3192 break;
3193 case greenland::IntrinsicHelper::HLIPutShort:
3194 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3195 false /* obj */);
3196 break;
3197
3198 case greenland::IntrinsicHelper::IntToChar:
3199 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3200 break;
3201 case greenland::IntrinsicHelper::IntToShort:
3202 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3203 break;
3204 case greenland::IntrinsicHelper::IntToByte:
3205 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3206 break;
3207
TDYa1274ec8ccd2012-08-11 07:04:57 -07003208 case greenland::IntrinsicHelper::F2I:
3209 case greenland::IntrinsicHelper::D2I:
3210 case greenland::IntrinsicHelper::F2L:
3211 case greenland::IntrinsicHelper::D2L:
3212 cvtFPToInt(cUnit, callInst);
3213 break;
3214
buzbee0967a252012-09-14 10:43:54 -07003215 case greenland::IntrinsicHelper::CmplFloat:
3216 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3217 break;
3218 case greenland::IntrinsicHelper::CmpgFloat:
3219 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3220 break;
3221 case greenland::IntrinsicHelper::CmplDouble:
3222 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3223 break;
3224 case greenland::IntrinsicHelper::CmpgDouble:
3225 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3226 break;
3227
3228 case greenland::IntrinsicHelper::CmpLong:
3229 cvtLongCompare(cUnit, callInst);
3230 break;
3231
3232 case greenland::IntrinsicHelper::SHLLong:
3233 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
3234 break;
3235 case greenland::IntrinsicHelper::SHRLong:
3236 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3237 break;
3238 case greenland::IntrinsicHelper::USHRLong:
3239 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3240 break;
3241 case greenland::IntrinsicHelper::SHLInt:
3242 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3243 break;
3244 case greenland::IntrinsicHelper::SHRInt:
3245 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3246 break;
3247 case greenland::IntrinsicHelper::USHRInt:
3248 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3249 break;
3250
3251 case greenland::IntrinsicHelper::CatchTargets: {
3252 llvm::SwitchInst* swInst =
3253 llvm::dyn_cast<llvm::SwitchInst>(nextIt);
3254 DCHECK(swInst != NULL);
3255 /*
3256 * Discard the edges and the following conditional branch.
3257 * Do a direct branch to the default target (which is the
3258 * "work" portion of the pair.
3259 * TODO: awful code layout - rework
3260 */
3261 llvm::BasicBlock* targetBB = swInst->getDefaultDest();
3262 DCHECK(targetBB != NULL);
3263 opUnconditionalBranch(cUnit,
3264 cUnit->blockToLabelMap.Get(targetBB));
3265 ++it;
3266 // Set next bb to default target - improves code layout
3267 nextBB = targetBB;
3268 }
3269 break;
3270
3271 default:
3272 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3273 << cUnit->intrinsic_helper->GetName(id);
3274 }
3275 }
3276 break;
3277
3278 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3279 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3280 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3281 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3282 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3283 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3284 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3285 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3286 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
3287 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3288 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
3289 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3290 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3291 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3292 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3293 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
3294 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003295 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3296 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3297 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
3298
3299 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3300 break;
3301 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3302 break;
3303
3304 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3305
3306 case llvm::Instruction::Unreachable:
3307 break; // FIXME: can we really ignore these?
3308
3309 case llvm::Instruction::Shl:
3310 case llvm::Instruction::LShr:
3311 case llvm::Instruction::AShr:
3312 case llvm::Instruction::Invoke:
3313 case llvm::Instruction::FPToUI:
TDYa1274ec8ccd2012-08-11 07:04:57 -07003314 case llvm::Instruction::FPToSI:
buzbee0967a252012-09-14 10:43:54 -07003315 case llvm::Instruction::UIToFP:
3316 case llvm::Instruction::PtrToInt:
3317 case llvm::Instruction::IntToPtr:
3318 case llvm::Instruction::FCmp:
3319 case llvm::Instruction::URem:
3320 case llvm::Instruction::UDiv:
3321 case llvm::Instruction::Resume:
3322 case llvm::Instruction::Alloca:
3323 case llvm::Instruction::GetElementPtr:
3324 case llvm::Instruction::Fence:
3325 case llvm::Instruction::AtomicCmpXchg:
3326 case llvm::Instruction::AtomicRMW:
3327 case llvm::Instruction::BitCast:
3328 case llvm::Instruction::VAArg:
3329 case llvm::Instruction::Select:
3330 case llvm::Instruction::UserOp1:
3331 case llvm::Instruction::UserOp2:
3332 case llvm::Instruction::ExtractElement:
3333 case llvm::Instruction::InsertElement:
3334 case llvm::Instruction::ShuffleVector:
3335 case llvm::Instruction::ExtractValue:
3336 case llvm::Instruction::InsertValue:
3337 case llvm::Instruction::LandingPad:
3338 case llvm::Instruction::IndirectBr:
3339 case llvm::Instruction::Load:
3340 case llvm::Instruction::Store:
3341 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3342
3343 default:
3344 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3345 break;
buzbeead8f15e2012-06-18 14:49:45 -07003346 }
3347 }
buzbee2cfc6392012-05-07 14:51:40 -07003348
buzbee0967a252012-09-14 10:43:54 -07003349 if (headLIR != NULL) {
3350 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
buzbee2cfc6392012-05-07 14:51:40 -07003351 }
buzbee0967a252012-09-14 10:43:54 -07003352 if (nextBB != NULL) {
3353 bb = nextBB;
3354 nextBB = NULL;
buzbee6969d502012-06-15 16:40:31 -07003355 }
buzbee6969d502012-06-15 16:40:31 -07003356 }
buzbee2cfc6392012-05-07 14:51:40 -07003357 return false;
3358}
3359
3360/*
3361 * Convert LLVM_IR to MIR:
3362 * o Iterate through the LLVM_IR and construct a graph using
3363 * standard MIR building blocks.
3364 * o Perform a basic-block optimization pass to remove unnecessary
3365 * store/load sequences.
3366 * o Convert the LLVM Value operands into RegLocations where applicable.
3367 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3368 * o Perform register promotion
3369 * o Iterate through the graph a basic block at a time, generating
3370 * LIR.
3371 * o Assemble LIR as usual.
3372 * o Profit.
3373 */
3374void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3375{
buzbeead8f15e2012-06-18 14:49:45 -07003376 llvm::Function* func = cUnit->func;
3377 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003378 // Allocate a list for LIR basic block labels
3379 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07003380 (LIR*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3381 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003382 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003383 for (llvm::Function::iterator i = func->begin(),
3384 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003385 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3386 &labelList[nextLabel++]);
3387 }
buzbeead8f15e2012-06-18 14:49:45 -07003388
3389 /*
3390 * Keep honest - clear regLocations, Value => RegLocation,
3391 * promotion map and VmapTables.
3392 */
3393 cUnit->locMap.clear(); // Start fresh
3394 cUnit->regLocation = NULL;
3395 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3396 i++) {
3397 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3398 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3399 }
3400 cUnit->coreSpillMask = 0;
3401 cUnit->numCoreSpills = 0;
3402 cUnit->fpSpillMask = 0;
3403 cUnit->numFPSpills = 0;
3404 cUnit->coreVmapTable.clear();
3405 cUnit->fpVmapTable.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003406
3407 /*
3408 * At this point, we've lost all knowledge of register promotion.
3409 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003410 * exists - not required for correctness). Normally, this will
3411 * be the first instruction we encounter, so we won't have to iterate
3412 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003413 */
buzbeeca7a5e42012-08-20 11:12:18 -07003414 for (llvm::inst_iterator i = llvm::inst_begin(func),
3415 e = llvm::inst_end(func); i != e; ++i) {
3416 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(&*i);
3417 if (callInst != NULL) {
3418 llvm::Function* callee = callInst->getCalledFunction();
3419 greenland::IntrinsicHelper::IntrinsicId id =
3420 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3421 if (id == greenland::IntrinsicHelper::MethodInfo) {
3422 if (cUnit->printMe) {
3423 LOG(INFO) << "Found MethodInfo";
3424 }
3425 llvm::MDNode* regInfoNode = callInst->getMetadata("RegInfo");
3426 if (regInfoNode != NULL) {
3427 llvm::ConstantInt* numInsValue =
3428 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(0));
3429 llvm::ConstantInt* numRegsValue =
3430 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(1));
3431 llvm::ConstantInt* numOutsValue =
3432 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(2));
3433 llvm::ConstantInt* numCompilerTempsValue =
3434 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(3));
3435 llvm::ConstantInt* numSSARegsValue =
3436 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(4));
3437 if (cUnit->printMe) {
3438 LOG(INFO) << "RegInfo - Ins:" << numInsValue->getZExtValue()
3439 << ", Regs:" << numRegsValue->getZExtValue()
3440 << ", Outs:" << numOutsValue->getZExtValue()
3441 << ", CTemps:" << numCompilerTempsValue->getZExtValue()
3442 << ", SSARegs:" << numSSARegsValue->getZExtValue();
3443 }
3444 }
3445 llvm::MDNode* pmapInfoNode = callInst->getMetadata("PromotionMap");
3446 if (pmapInfoNode != NULL) {
3447 int elems = pmapInfoNode->getNumOperands();
3448 if (cUnit->printMe) {
3449 LOG(INFO) << "PMap size: " << elems;
3450 }
3451 for (int i = 0; i < elems; i++) {
3452 llvm::ConstantInt* rawMapData =
3453 static_cast<llvm::ConstantInt*>(pmapInfoNode->getOperand(i));
3454 uint32_t mapData = rawMapData->getZExtValue();
3455 PromotionMap* p = &cUnit->promotionMap[i];
3456 p->firstInPair = (mapData >> 24) & 0xff;
3457 p->fpReg = (mapData >> 16) & 0xff;
3458 p->coreReg = (mapData >> 8) & 0xff;
3459 p->fpLocation = static_cast<RegLocationType>((mapData >> 4) & 0xf);
3460 if (p->fpLocation == kLocPhysReg) {
3461 oatRecordFpPromotion(cUnit, p->fpReg, i);
3462 }
3463 p->coreLocation = static_cast<RegLocationType>(mapData & 0xf);
3464 if (p->coreLocation == kLocPhysReg) {
3465 oatRecordCorePromotion(cUnit, p->coreReg, i);
3466 }
3467 }
3468 if (cUnit->printMe) {
3469 oatDumpPromotionMap(cUnit);
3470 }
3471 }
3472 break;
3473 }
3474 }
3475 }
3476 oatAdjustSpillMask(cUnit);
3477 cUnit->frameSize = oatComputeFrameSize(cUnit);
buzbeead8f15e2012-06-18 14:49:45 -07003478
3479 // Create RegLocations for arguments
3480 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3481 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3482 for (; it != it_end; ++it) {
3483 llvm::Value* val = it;
3484 createLocFromValue(cUnit, val);
3485 }
3486 // Create RegLocations for all non-argument defintions
3487 for (llvm::inst_iterator i = llvm::inst_begin(func),
3488 e = llvm::inst_end(func); i != e; ++i) {
3489 llvm::Value* val = &*i;
3490 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3491 createLocFromValue(cUnit, val);
3492 }
3493 }
3494
buzbee2cfc6392012-05-07 14:51:40 -07003495 // Walk the blocks, generating code.
3496 for (llvm::Function::iterator i = cUnit->func->begin(),
3497 e = cUnit->func->end(); i != e; ++i) {
3498 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3499 }
3500
3501 handleSuspendLaunchpads(cUnit);
3502
3503 handleThrowLaunchpads(cUnit);
3504
3505 handleIntrinsicLaunchpads(cUnit);
3506
buzbee692be802012-08-29 15:52:59 -07003507 cUnit->func->eraseFromParent();
3508 cUnit->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003509}
3510
3511
3512} // namespace art
3513
3514#endif // ART_USE_QUICK_COMPILER