blob: 6f2c52d97d31c74eb765a1bcd8b10c5daaef309c [file] [log] [blame]
buzbee2cfc6392012-05-07 14:51:40 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#if defined(ART_USE_QUICK_COMPILER)
18
19#include "object_utils.h"
20
21#include <llvm/Support/ToolOutputFile.h>
22#include <llvm/Bitcode/ReaderWriter.h>
23#include <llvm/Analysis/Verifier.h>
24#include <llvm/Metadata.h>
25#include <llvm/ADT/DepthFirstIterator.h>
26#include <llvm/Instruction.h>
27#include <llvm/Type.h>
28#include <llvm/Instructions.h>
29#include <llvm/Support/Casting.h>
buzbeead8f15e2012-06-18 14:49:45 -070030#include <llvm/Support/InstIterator.h>
buzbee2cfc6392012-05-07 14:51:40 -070031
buzbee8320f382012-09-11 16:29:42 -070032static const char* kLabelFormat = "%c0x%x_%d";
33static const char kNormalBlock = 'L';
34static const char kCatchBlock = 'C';
buzbee2cfc6392012-05-07 14:51:40 -070035
36namespace art {
37extern const RegLocation badLoc;
buzbeeb03f4872012-06-11 15:22:11 -070038RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070039
40llvm::BasicBlock* getLLVMBlock(CompilationUnit* cUnit, int id)
41{
42 return cUnit->idToBlockMap.Get(id);
43}
44
45llvm::Value* getLLVMValue(CompilationUnit* cUnit, int sReg)
46{
47 return (llvm::Value*)oatGrowableListGetElement(&cUnit->llvmValues, sReg);
48}
49
50// Replace the placeholder value with the real definition
51void defineValue(CompilationUnit* cUnit, llvm::Value* val, int sReg)
52{
53 llvm::Value* placeholder = getLLVMValue(cUnit, sReg);
buzbee9a2487f2012-07-26 14:01:13 -070054 if (placeholder == NULL) {
55 // This can happen on instruction rewrite on verification failure
Bill Buzbeec9f40dd2012-08-15 11:35:25 -070056 LOG(WARNING) << "Null placeholder";
buzbee9a2487f2012-07-26 14:01:13 -070057 return;
58 }
buzbee2cfc6392012-05-07 14:51:40 -070059 placeholder->replaceAllUsesWith(val);
60 val->takeName(placeholder);
61 cUnit->llvmValues.elemList[sReg] = (intptr_t)val;
buzbee4be777b2012-07-12 14:38:18 -070062 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
63 DCHECK(inst != NULL);
64 inst->eraseFromParent();
buzbee2cfc6392012-05-07 14:51:40 -070065}
66
67llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
68{
69 llvm::Type* res = NULL;
70 if (loc.wide) {
71 if (loc.fp)
buzbee4f1181f2012-06-22 13:52:12 -070072 res = cUnit->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070073 else
buzbee4f1181f2012-06-22 13:52:12 -070074 res = cUnit->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070075 } else {
76 if (loc.fp) {
buzbee4f1181f2012-06-22 13:52:12 -070077 res = cUnit->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070078 } else {
79 if (loc.ref)
80 res = cUnit->irb->GetJObjectTy();
81 else
buzbee4f1181f2012-06-22 13:52:12 -070082 res = cUnit->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -070083 }
84 }
85 return res;
86}
87
buzbeead8f15e2012-06-18 14:49:45 -070088/* Create an in-memory RegLocation from an llvm Value. */
89void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
90{
91 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
92 std::string s(val->getName().str());
93 const char* valName = s.c_str();
buzbeead8f15e2012-06-18 14:49:45 -070094 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
95 DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
96 int baseSReg = INVALID_SREG;
97 int subscript = -1;
98 sscanf(valName, "v%d_%d", &baseSReg, &subscript);
99 if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
100 baseSReg = SSA_METHOD_BASEREG;
101 subscript = 0;
102 }
buzbeead8f15e2012-06-18 14:49:45 -0700103 DCHECK_NE(baseSReg, INVALID_SREG);
104 DCHECK_NE(subscript, -1);
105 // TODO: redo during C++'ification
106 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
107 INVALID_REG, INVALID_SREG, INVALID_SREG};
108 llvm::Type* ty = val->getType();
109 loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
110 (ty == cUnit->irb->getDoubleTy()));
111 loc.defined = true;
buzbeeca7a5e42012-08-20 11:12:18 -0700112 loc.home = false; // May change during promotion
buzbeead8f15e2012-06-18 14:49:45 -0700113 loc.sRegLow = baseSReg;
114 loc.origSReg = cUnit->locMap.size();
buzbeeca7a5e42012-08-20 11:12:18 -0700115 PromotionMap pMap = cUnit->promotionMap[baseSReg];
116 if (ty == cUnit->irb->getFloatTy()) {
117 loc.fp = true;
118 if (pMap.fpLocation == kLocPhysReg) {
119 loc.lowReg = pMap.fpReg;
120 loc.location = kLocPhysReg;
121 loc.home = true;
122 }
123 } else if (ty == cUnit->irb->getDoubleTy()) {
124 loc.fp = true;
125 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
126 if ((pMap.fpLocation == kLocPhysReg) &&
127 (pMapHigh.fpLocation == kLocPhysReg) &&
128 ((pMap.fpReg & 0x1) == 0) &&
129 (pMap.fpReg + 1 == pMapHigh.fpReg)) {
130 loc.lowReg = pMap.fpReg;
131 loc.highReg = pMapHigh.fpReg;
132 loc.location = kLocPhysReg;
133 loc.home = true;
134 }
135 } else if (ty == cUnit->irb->GetJObjectTy()) {
136 loc.ref = true;
137 if (pMap.coreLocation == kLocPhysReg) {
138 loc.lowReg = pMap.coreReg;
139 loc.location = kLocPhysReg;
140 loc.home = true;
141 }
142 } else if (ty == cUnit->irb->getInt64Ty()) {
143 loc.core = true;
144 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
145 if ((pMap.coreLocation == kLocPhysReg) &&
146 (pMapHigh.coreLocation == kLocPhysReg)) {
147 loc.lowReg = pMap.coreReg;
148 loc.highReg = pMapHigh.coreReg;
149 loc.location = kLocPhysReg;
150 loc.home = true;
151 }
152 } else {
153 loc.core = true;
154 if (pMap.coreLocation == kLocPhysReg) {
155 loc.lowReg = pMap.coreReg;
156 loc.location = kLocPhysReg;
157 loc.home = true;
158 }
159 }
160
161 if (cUnit->printMe && loc.home) {
162 if (loc.wide) {
buzbee0967a252012-09-14 10:43:54 -0700163 LOG(INFO) << "Promoted wide " << s << " to regs " << static_cast<int>(loc.lowReg)
buzbeeca7a5e42012-08-20 11:12:18 -0700164 << "/" << loc.highReg;
165 } else {
buzbee0967a252012-09-14 10:43:54 -0700166 LOG(INFO) << "Promoted " << s << " to reg " << static_cast<int>(loc.lowReg);
buzbeeca7a5e42012-08-20 11:12:18 -0700167 }
168 }
buzbeead8f15e2012-06-18 14:49:45 -0700169 cUnit->locMap.Put(val, loc);
170}
buzbee2cfc6392012-05-07 14:51:40 -0700171void initIR(CompilationUnit* cUnit)
172{
buzbee692be802012-08-29 15:52:59 -0700173 QuickCompiler* quick =
174 reinterpret_cast<QuickCompiler*>(cUnit->compiler->GetCompilerContext());
175 cUnit->context = quick->GetLLVMContext();
176 cUnit->module = quick->GetLLVMModule();
177 cUnit->intrinsic_helper = quick->GetIntrinsicHelper();
178 cUnit->irb = quick->GetIRBuilder();
buzbee2cfc6392012-05-07 14:51:40 -0700179}
180
181const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
182 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
183}
184
buzbeef58c12c2012-07-03 15:06:29 -0700185llvm::BasicBlock* findCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
186{
187 BasicBlock* bb = oatFindBlock(cUnit, vaddr);
188 DCHECK(bb != NULL);
189 return getLLVMBlock(cUnit, bb->id);
190}
191
192void convertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
193 int32_t tableOffset, RegLocation rlSrc)
194{
195 const Instruction::PackedSwitchPayload* payload =
196 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
197 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
198
199 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
200
201 llvm::SwitchInst* sw =
202 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
203 payload->case_count);
204
205 for (uint16_t i = 0; i < payload->case_count; ++i) {
206 llvm::BasicBlock* llvmBB =
207 findCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
208 sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
209 }
210 llvm::MDNode* switchNode =
211 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
212 sw->setMetadata("SwitchTable", switchNode);
213 bb->taken = NULL;
214 bb->fallThrough = NULL;
215}
216
buzbeea1da8a52012-07-09 14:00:21 -0700217void convertSparseSwitch(CompilationUnit* cUnit, BasicBlock* bb,
218 int32_t tableOffset, RegLocation rlSrc)
219{
220 const Instruction::SparseSwitchPayload* payload =
221 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
222 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
223
224 const int32_t* keys = payload->GetKeys();
225 const int32_t* targets = payload->GetTargets();
226
227 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
228
229 llvm::SwitchInst* sw =
230 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
231 payload->case_count);
232
233 for (size_t i = 0; i < payload->case_count; ++i) {
234 llvm::BasicBlock* llvmBB =
235 findCaseTarget(cUnit, cUnit->currentDalvikOffset + targets[i]);
236 sw->addCase(cUnit->irb->getInt32(keys[i]), llvmBB);
237 }
238 llvm::MDNode* switchNode =
239 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
240 sw->setMetadata("SwitchTable", switchNode);
241 bb->taken = NULL;
242 bb->fallThrough = NULL;
243}
244
buzbee8fa0fda2012-06-27 15:44:52 -0700245void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
246 greenland::IntrinsicHelper::IntrinsicId id,
247 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700248{
buzbee8fa0fda2012-06-27 15:44:52 -0700249 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700250 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700251 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
252 defineValue(cUnit, res, rlDest.origSReg);
253}
254
255void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
256 greenland::IntrinsicHelper::IntrinsicId id,
257 RegLocation rlSrc)
258{
259 llvm::SmallVector<llvm::Value*, 2> args;
260 args.push_back(cUnit->irb->getInt32(fieldIndex));
261 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
262 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
263 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700264}
265
buzbee101305f2012-06-28 18:00:56 -0700266void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
267 RegLocation rlArray)
268{
269 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700270 id = greenland::IntrinsicHelper::HLFillArrayData;
buzbee101305f2012-06-28 18:00:56 -0700271 llvm::SmallVector<llvm::Value*, 2> args;
272 args.push_back(cUnit->irb->getInt32(offset));
273 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
274 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
275 cUnit->irb->CreateCall(intr, args);
276}
277
buzbee2cfc6392012-05-07 14:51:40 -0700278llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
279 RegLocation loc)
280{
281 greenland::IntrinsicHelper::IntrinsicId id;
282 if (loc.wide) {
283 if (loc.fp) {
284 id = greenland::IntrinsicHelper::ConstDouble;
285 } else {
286 id = greenland::IntrinsicHelper::ConstLong;
287 }
288 } else {
289 if (loc.fp) {
290 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700291 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700292 id = greenland::IntrinsicHelper::ConstObj;
293 } else {
294 id = greenland::IntrinsicHelper::ConstInt;
295 }
296 }
297 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
298 return cUnit->irb->CreateCall(intr, src);
299}
buzbeeb03f4872012-06-11 15:22:11 -0700300
301void emitPopShadowFrame(CompilationUnit* cUnit)
302{
303 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
304 greenland::IntrinsicHelper::PopShadowFrame);
305 cUnit->irb->CreateCall(intr);
306}
307
buzbee2cfc6392012-05-07 14:51:40 -0700308llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
309 RegLocation loc)
310{
311 greenland::IntrinsicHelper::IntrinsicId id;
312 if (loc.wide) {
313 if (loc.fp) {
314 id = greenland::IntrinsicHelper::CopyDouble;
315 } else {
316 id = greenland::IntrinsicHelper::CopyLong;
317 }
318 } else {
319 if (loc.fp) {
320 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700321 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700322 id = greenland::IntrinsicHelper::CopyObj;
323 } else {
324 id = greenland::IntrinsicHelper::CopyInt;
325 }
326 }
327 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
328 return cUnit->irb->CreateCall(intr, src);
329}
330
buzbee32412962012-06-26 16:27:56 -0700331void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
332{
333 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
334 greenland::IntrinsicHelper::GetException);
335 llvm::Value* res = cUnit->irb->CreateCall(func);
336 defineValue(cUnit, res, rlDest.origSReg);
337}
338
339void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
340{
341 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
342 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
TDYa127f71bf5a2012-07-29 20:09:52 -0700343 greenland::IntrinsicHelper::HLThrowException);
buzbee32412962012-06-26 16:27:56 -0700344 cUnit->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700345}
346
buzbee8fa0fda2012-06-27 15:44:52 -0700347void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
348 greenland::IntrinsicHelper::IntrinsicId id,
349 RegLocation rlSrc)
350{
351 llvm::SmallVector<llvm::Value*, 2> args;
352 args.push_back(cUnit->irb->getInt32(optFlags));
353 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
354 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
355 cUnit->irb->CreateCall(func, args);
356}
357
buzbee76592632012-06-29 15:18:35 -0700358void convertArrayLength(CompilationUnit* cUnit, int optFlags,
359 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700360{
361 llvm::SmallVector<llvm::Value*, 2> args;
362 args.push_back(cUnit->irb->getInt32(optFlags));
363 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
364 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700365 greenland::IntrinsicHelper::OptArrayLength);
buzbee76592632012-06-29 15:18:35 -0700366 llvm::Value* res = cUnit->irb->CreateCall(func, args);
367 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700368}
369
buzbee2cfc6392012-05-07 14:51:40 -0700370void emitSuspendCheck(CompilationUnit* cUnit)
371{
372 greenland::IntrinsicHelper::IntrinsicId id =
373 greenland::IntrinsicHelper::CheckSuspend;
374 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
375 cUnit->irb->CreateCall(intr);
376}
377
378llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
379 llvm::Value* src1, llvm::Value* src2)
380{
381 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700382 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700383 switch(cc) {
384 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
385 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
386 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
387 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
388 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
389 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
390 default: LOG(FATAL) << "Unexpected cc value " << cc;
391 }
392 return res;
393}
394
395void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
396 ConditionCode cc, RegLocation rlSrc1,
397 RegLocation rlSrc2)
398{
399 if (bb->taken->startOffset <= mir->offset) {
400 emitSuspendCheck(cUnit);
401 }
402 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
403 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
404 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
405 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
406 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
407 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700408 // Don't redo the fallthrough branch in the BB driver
409 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700410}
411
412void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
413 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
414{
415 if (bb->taken->startOffset <= mir->offset) {
416 emitSuspendCheck(cUnit);
417 }
418 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
419 llvm::Value* src2;
420 if (rlSrc1.ref) {
421 src2 = cUnit->irb->GetJNull();
422 } else {
423 src2 = cUnit->irb->getInt32(0);
424 }
425 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700426 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
427 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700428 // Don't redo the fallthrough branch in the BB driver
429 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700430}
431
432llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
433 llvm::Value* src1, llvm::Value* src2)
434{
435 greenland::IntrinsicHelper::IntrinsicId id;
436 if (isLong) {
437 if (isDiv) {
438 id = greenland::IntrinsicHelper::DivLong;
439 } else {
440 id = greenland::IntrinsicHelper::RemLong;
441 }
Logan Chien554e6072012-07-23 20:00:01 -0700442 } else {
443 if (isDiv) {
buzbee2cfc6392012-05-07 14:51:40 -0700444 id = greenland::IntrinsicHelper::DivInt;
445 } else {
446 id = greenland::IntrinsicHelper::RemInt;
Logan Chien554e6072012-07-23 20:00:01 -0700447 }
buzbee2cfc6392012-05-07 14:51:40 -0700448 }
449 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
450 llvm::SmallVector<llvm::Value*, 2>args;
451 args.push_back(src1);
452 args.push_back(src2);
453 return cUnit->irb->CreateCall(intr, args);
454}
455
456llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
457 llvm::Value* src1, llvm::Value* src2)
458{
459 llvm::Value* res = NULL;
460 switch(op) {
461 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
462 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700463 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700464 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
465 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
466 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
467 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
468 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
469 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700470 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
471 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
472 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700473 default:
474 LOG(FATAL) << "Invalid op " << op;
475 }
476 return res;
477}
478
479void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
480 RegLocation rlSrc1, RegLocation rlSrc2)
481{
482 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
483 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
484 llvm::Value* res = NULL;
485 switch(op) {
486 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
487 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
488 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
489 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
490 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
491 default:
492 LOG(FATAL) << "Invalid op " << op;
493 }
494 defineValue(cUnit, res, rlDest.origSReg);
495}
496
buzbee2a83e8f2012-07-13 16:42:30 -0700497void convertShift(CompilationUnit* cUnit,
498 greenland::IntrinsicHelper::IntrinsicId id,
499 RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
buzbee4f1181f2012-06-22 13:52:12 -0700500{
buzbee2a83e8f2012-07-13 16:42:30 -0700501 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
502 llvm::SmallVector<llvm::Value*, 2>args;
503 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
504 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
505 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
506 defineValue(cUnit, res, rlDest.origSReg);
507}
508
509void convertShiftLit(CompilationUnit* cUnit,
510 greenland::IntrinsicHelper::IntrinsicId id,
511 RegLocation rlDest, RegLocation rlSrc, int shiftAmount)
512{
513 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
514 llvm::SmallVector<llvm::Value*, 2>args;
515 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
516 args.push_back(cUnit->irb->getInt32(shiftAmount));
517 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700518 defineValue(cUnit, res, rlDest.origSReg);
519}
520
buzbee2cfc6392012-05-07 14:51:40 -0700521void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
522 RegLocation rlSrc1, RegLocation rlSrc2)
523{
524 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
525 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700526 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700527 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
528 defineValue(cUnit, res, rlDest.origSReg);
529}
530
buzbeeb03f4872012-06-11 15:22:11 -0700531void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
532{
533 int index = -1;
534 DCHECK(newVal != NULL);
535 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
536 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
537 if (cUnit->shadowMap[i] == vReg) {
538 index = i;
539 break;
540 }
541 }
Elliott Hughes74847412012-06-20 18:10:21 -0700542 DCHECK_NE(index, -1) << "Corrupt shadowMap";
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: {
buzbee6969d502012-06-15 16:40:31 -0700925 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700926 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
927 defineValue(cUnit, res, rlDest.origSReg);
928 }
929 break;
930
931 case Instruction::CONST_WIDE_16:
932 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700933 // Sign extend to 64 bits
934 int64_t imm = static_cast<int32_t>(vB);
935 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700936 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
937 defineValue(cUnit, res, rlDest.origSReg);
938 }
939 break;
940
941 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700942 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700943 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
944 defineValue(cUnit, res, rlDest.origSReg);
945 }
946 break;
947
948 case Instruction::CONST_WIDE: {
949 llvm::Constant* immValue =
950 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
951 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
952 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700953 }
954 break;
buzbee2cfc6392012-05-07 14:51:40 -0700955 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700956 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700957 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
958 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
959 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700960 }
961 break;
962
buzbee8fa0fda2012-06-27 15:44:52 -0700963 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700964 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700965 rlSrc[0]);
966 break;
967 case Instruction::SPUT:
968 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700969 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700970 rlSrc[0]);
971 } else {
buzbee76592632012-06-29 15:18:35 -0700972 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700973 }
974 break;
975 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700976 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700977 rlSrc[0]);
978 break;
979 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700980 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700981 break;
982 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700983 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700984 break;
985 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -0700986 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700987 break;
988 case Instruction::SPUT_WIDE:
989 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700990 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -0700991 rlSrc[0]);
992 } else {
buzbee76592632012-06-29 15:18:35 -0700993 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -0700994 rlSrc[0]);
995 }
996 break;
997
998 case Instruction::SGET_OBJECT:
999 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
1000 break;
1001 case Instruction::SGET:
1002 if (rlDest.fp) {
1003 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
1004 } else {
1005 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
1006 }
1007 break;
1008 case Instruction::SGET_BOOLEAN:
1009 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
1010 break;
1011 case Instruction::SGET_BYTE:
1012 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
1013 break;
1014 case Instruction::SGET_CHAR:
1015 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
1016 break;
1017 case Instruction::SGET_SHORT:
1018 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
1019 break;
1020 case Instruction::SGET_WIDE:
1021 if (rlDest.fp) {
1022 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
1023 rlDest);
1024 } else {
1025 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001026 }
1027 break;
buzbee2cfc6392012-05-07 14:51:40 -07001028
1029 case Instruction::RETURN_WIDE:
1030 case Instruction::RETURN:
1031 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -07001032 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001033 emitSuspendCheck(cUnit);
1034 }
buzbeeb03f4872012-06-11 15:22:11 -07001035 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001036 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
1037 bb->hasReturn = true;
1038 }
1039 break;
1040
1041 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001042 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001043 emitSuspendCheck(cUnit);
1044 }
buzbeeb03f4872012-06-11 15:22:11 -07001045 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001046 cUnit->irb->CreateRetVoid();
1047 bb->hasReturn = true;
1048 }
1049 break;
1050
1051 case Instruction::IF_EQ:
1052 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1053 break;
1054 case Instruction::IF_NE:
1055 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1056 break;
1057 case Instruction::IF_LT:
1058 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1059 break;
1060 case Instruction::IF_GE:
1061 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1062 break;
1063 case Instruction::IF_GT:
1064 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1065 break;
1066 case Instruction::IF_LE:
1067 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1068 break;
1069 case Instruction::IF_EQZ:
1070 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1071 break;
1072 case Instruction::IF_NEZ:
1073 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1074 break;
1075 case Instruction::IF_LTZ:
1076 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1077 break;
1078 case Instruction::IF_GEZ:
1079 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1080 break;
1081 case Instruction::IF_GTZ:
1082 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1083 break;
1084 case Instruction::IF_LEZ:
1085 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1086 break;
1087
1088 case Instruction::GOTO:
1089 case Instruction::GOTO_16:
1090 case Instruction::GOTO_32: {
1091 if (bb->taken->startOffset <= bb->startOffset) {
1092 emitSuspendCheck(cUnit);
1093 }
1094 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1095 }
1096 break;
1097
1098 case Instruction::ADD_LONG:
1099 case Instruction::ADD_LONG_2ADDR:
1100 case Instruction::ADD_INT:
1101 case Instruction::ADD_INT_2ADDR:
1102 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1103 break;
1104 case Instruction::SUB_LONG:
1105 case Instruction::SUB_LONG_2ADDR:
1106 case Instruction::SUB_INT:
1107 case Instruction::SUB_INT_2ADDR:
1108 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1109 break;
1110 case Instruction::MUL_LONG:
1111 case Instruction::MUL_LONG_2ADDR:
1112 case Instruction::MUL_INT:
1113 case Instruction::MUL_INT_2ADDR:
1114 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1115 break;
1116 case Instruction::DIV_LONG:
1117 case Instruction::DIV_LONG_2ADDR:
1118 case Instruction::DIV_INT:
1119 case Instruction::DIV_INT_2ADDR:
1120 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1121 break;
1122 case Instruction::REM_LONG:
1123 case Instruction::REM_LONG_2ADDR:
1124 case Instruction::REM_INT:
1125 case Instruction::REM_INT_2ADDR:
1126 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1127 break;
1128 case Instruction::AND_LONG:
1129 case Instruction::AND_LONG_2ADDR:
1130 case Instruction::AND_INT:
1131 case Instruction::AND_INT_2ADDR:
1132 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1133 break;
1134 case Instruction::OR_LONG:
1135 case Instruction::OR_LONG_2ADDR:
1136 case Instruction::OR_INT:
1137 case Instruction::OR_INT_2ADDR:
1138 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1139 break;
1140 case Instruction::XOR_LONG:
1141 case Instruction::XOR_LONG_2ADDR:
1142 case Instruction::XOR_INT:
1143 case Instruction::XOR_INT_2ADDR:
1144 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1145 break;
1146 case Instruction::SHL_LONG:
1147 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001148 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1149 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001150 break;
buzbee2cfc6392012-05-07 14:51:40 -07001151 case Instruction::SHL_INT:
1152 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001153 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1154 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001155 break;
1156 case Instruction::SHR_LONG:
1157 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001158 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1159 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001160 break;
buzbee2cfc6392012-05-07 14:51:40 -07001161 case Instruction::SHR_INT:
1162 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001163 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1164 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001165 break;
1166 case Instruction::USHR_LONG:
1167 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001168 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1169 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001170 break;
buzbee2cfc6392012-05-07 14:51:40 -07001171 case Instruction::USHR_INT:
1172 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001173 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1174 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001175 break;
1176
1177 case Instruction::ADD_INT_LIT16:
1178 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001179 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001180 break;
1181 case Instruction::RSUB_INT:
1182 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001183 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001184 break;
1185 case Instruction::MUL_INT_LIT16:
1186 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001187 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001188 break;
1189 case Instruction::DIV_INT_LIT16:
1190 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001191 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001192 break;
1193 case Instruction::REM_INT_LIT16:
1194 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001195 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001196 break;
1197 case Instruction::AND_INT_LIT16:
1198 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001199 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001200 break;
1201 case Instruction::OR_INT_LIT16:
1202 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001203 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001204 break;
1205 case Instruction::XOR_INT_LIT16:
1206 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001207 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001208 break;
1209 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001210 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1211 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001212 break;
1213 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001214 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1215 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001216 break;
1217 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001218 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1219 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001220 break;
1221
1222 case Instruction::ADD_FLOAT:
1223 case Instruction::ADD_FLOAT_2ADDR:
1224 case Instruction::ADD_DOUBLE:
1225 case Instruction::ADD_DOUBLE_2ADDR:
1226 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1227 break;
1228
1229 case Instruction::SUB_FLOAT:
1230 case Instruction::SUB_FLOAT_2ADDR:
1231 case Instruction::SUB_DOUBLE:
1232 case Instruction::SUB_DOUBLE_2ADDR:
1233 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1234 break;
1235
1236 case Instruction::MUL_FLOAT:
1237 case Instruction::MUL_FLOAT_2ADDR:
1238 case Instruction::MUL_DOUBLE:
1239 case Instruction::MUL_DOUBLE_2ADDR:
1240 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1241 break;
1242
1243 case Instruction::DIV_FLOAT:
1244 case Instruction::DIV_FLOAT_2ADDR:
1245 case Instruction::DIV_DOUBLE:
1246 case Instruction::DIV_DOUBLE_2ADDR:
1247 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1248 break;
1249
1250 case Instruction::REM_FLOAT:
1251 case Instruction::REM_FLOAT_2ADDR:
1252 case Instruction::REM_DOUBLE:
1253 case Instruction::REM_DOUBLE_2ADDR:
1254 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1255 break;
1256
buzbee6969d502012-06-15 16:40:31 -07001257 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001258 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1259 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001260 break;
1261 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001262 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1263 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001264 break;
1265
1266 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001267 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1268 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001269 break;
1270 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001271 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1272 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001273 break;
1274
1275 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001276 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1277 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001278 break;
1279 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001280 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1281 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001282 break;
1283
1284 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001285 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1286 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001287 break;
1288 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001289 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1290 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001291 break;
1292
1293 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001294 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1295 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001296 break;
1297 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001298 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1299 false /* NewFilledArray */);
1300 break;
1301 case Instruction::FILLED_NEW_ARRAY:
1302 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1303 true /* NewFilledArray */);
1304 break;
1305 case Instruction::FILLED_NEW_ARRAY_RANGE:
1306 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1307 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001308 break;
1309
1310 case Instruction::CONST_STRING:
1311 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001312 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1313 rlDest);
1314 break;
1315
1316 case Instruction::CONST_CLASS:
1317 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1318 rlDest);
1319 break;
1320
1321 case Instruction::CHECK_CAST:
1322 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001323 break;
1324
buzbee4f1181f2012-06-22 13:52:12 -07001325 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001326 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001327 break;
1328
buzbee32412962012-06-26 16:27:56 -07001329 case Instruction::MOVE_EXCEPTION:
1330 convertMoveException(cUnit, rlDest);
1331 break;
1332
1333 case Instruction::THROW:
1334 convertThrow(cUnit, rlSrc[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001335 /*
1336 * If this throw is standalone, terminate.
1337 * If it might rethrow, force termination
1338 * of the following block.
1339 */
1340 if (bb->fallThrough == NULL) {
1341 cUnit->irb->CreateUnreachable();
1342 } else {
1343 bb->fallThrough->fallThrough = NULL;
1344 bb->fallThrough->taken = NULL;
1345 }
buzbee32412962012-06-26 16:27:56 -07001346 break;
1347
buzbee2cfc6392012-05-07 14:51:40 -07001348 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001349 case Instruction::MOVE_RESULT:
1350 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001351 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001352 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001353 */
jeffhao9a4f0032012-08-30 16:17:40 -07001354 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001355 break;
1356
1357 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001358 convertMonitorEnterExit(cUnit, optFlags,
1359 greenland::IntrinsicHelper::MonitorEnter,
1360 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001361 break;
1362
1363 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001364 convertMonitorEnterExit(cUnit, optFlags,
1365 greenland::IntrinsicHelper::MonitorExit,
1366 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001367 break;
1368
1369 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001370 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001371 break;
1372
1373 case Instruction::NEW_ARRAY:
1374 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1375 break;
1376
1377 case Instruction::INSTANCE_OF:
1378 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1379 break;
1380
1381 case Instruction::AGET:
1382 if (rlDest.fp) {
1383 convertAget(cUnit, optFlags,
1384 greenland::IntrinsicHelper::HLArrayGetFloat,
1385 rlDest, rlSrc[0], rlSrc[1]);
1386 } else {
1387 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1388 rlDest, rlSrc[0], rlSrc[1]);
1389 }
1390 break;
1391 case Instruction::AGET_OBJECT:
1392 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1393 rlDest, rlSrc[0], rlSrc[1]);
1394 break;
1395 case Instruction::AGET_BOOLEAN:
1396 convertAget(cUnit, optFlags,
1397 greenland::IntrinsicHelper::HLArrayGetBoolean,
1398 rlDest, rlSrc[0], rlSrc[1]);
1399 break;
1400 case Instruction::AGET_BYTE:
1401 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1402 rlDest, rlSrc[0], rlSrc[1]);
1403 break;
1404 case Instruction::AGET_CHAR:
1405 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1406 rlDest, rlSrc[0], rlSrc[1]);
1407 break;
1408 case Instruction::AGET_SHORT:
1409 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1410 rlDest, rlSrc[0], rlSrc[1]);
1411 break;
1412 case Instruction::AGET_WIDE:
1413 if (rlDest.fp) {
1414 convertAget(cUnit, optFlags,
1415 greenland::IntrinsicHelper::HLArrayGetDouble,
1416 rlDest, rlSrc[0], rlSrc[1]);
1417 } else {
1418 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1419 rlDest, rlSrc[0], rlSrc[1]);
1420 }
1421 break;
1422
1423 case Instruction::APUT:
1424 if (rlSrc[0].fp) {
1425 convertAput(cUnit, optFlags,
1426 greenland::IntrinsicHelper::HLArrayPutFloat,
1427 rlSrc[0], rlSrc[1], rlSrc[2]);
1428 } else {
1429 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1430 rlSrc[0], rlSrc[1], rlSrc[2]);
1431 }
1432 break;
1433 case Instruction::APUT_OBJECT:
1434 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1435 rlSrc[0], rlSrc[1], rlSrc[2]);
1436 break;
1437 case Instruction::APUT_BOOLEAN:
1438 convertAput(cUnit, optFlags,
1439 greenland::IntrinsicHelper::HLArrayPutBoolean,
1440 rlSrc[0], rlSrc[1], rlSrc[2]);
1441 break;
1442 case Instruction::APUT_BYTE:
1443 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1444 rlSrc[0], rlSrc[1], rlSrc[2]);
1445 break;
1446 case Instruction::APUT_CHAR:
1447 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1448 rlSrc[0], rlSrc[1], rlSrc[2]);
1449 break;
1450 case Instruction::APUT_SHORT:
1451 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1452 rlSrc[0], rlSrc[1], rlSrc[2]);
1453 break;
1454 case Instruction::APUT_WIDE:
1455 if (rlSrc[0].fp) {
1456 convertAput(cUnit, optFlags,
1457 greenland::IntrinsicHelper::HLArrayPutDouble,
1458 rlSrc[0], rlSrc[1], rlSrc[2]);
1459 } else {
1460 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1461 rlSrc[0], rlSrc[1], rlSrc[2]);
1462 }
1463 break;
1464
buzbee101305f2012-06-28 18:00:56 -07001465 case Instruction::IGET:
1466 if (rlDest.fp) {
1467 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001468 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001469 } else {
1470 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001471 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001472 }
buzbee2cfc6392012-05-07 14:51:40 -07001473 break;
buzbee101305f2012-06-28 18:00:56 -07001474 case Instruction::IGET_OBJECT:
1475 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001476 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001477 break;
1478 case Instruction::IGET_BOOLEAN:
1479 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001480 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001481 break;
1482 case Instruction::IGET_BYTE:
1483 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001484 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001485 break;
1486 case Instruction::IGET_CHAR:
1487 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001488 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001489 break;
1490 case Instruction::IGET_SHORT:
1491 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001492 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001493 break;
1494 case Instruction::IGET_WIDE:
1495 if (rlDest.fp) {
1496 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001497 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001498 } else {
1499 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001500 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001501 }
1502 break;
1503 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001504 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001505 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1506 rlSrc[0], rlSrc[1], vC);
1507 } else {
1508 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1509 rlSrc[0], rlSrc[1], vC);
1510 }
1511 break;
1512 case Instruction::IPUT_OBJECT:
1513 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1514 rlSrc[0], rlSrc[1], vC);
1515 break;
1516 case Instruction::IPUT_BOOLEAN:
1517 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1518 rlSrc[0], rlSrc[1], vC);
1519 break;
1520 case Instruction::IPUT_BYTE:
1521 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1522 rlSrc[0], rlSrc[1], vC);
1523 break;
1524 case Instruction::IPUT_CHAR:
1525 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1526 rlSrc[0], rlSrc[1], vC);
1527 break;
1528 case Instruction::IPUT_SHORT:
1529 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1530 rlSrc[0], rlSrc[1], vC);
1531 break;
1532 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001533 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001534 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1535 rlSrc[0], rlSrc[1], vC);
1536 } else {
1537 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1538 rlSrc[0], rlSrc[1], vC);
1539 }
buzbee2cfc6392012-05-07 14:51:40 -07001540 break;
1541
1542 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001543 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001544 break;
1545
buzbee76592632012-06-29 15:18:35 -07001546 case Instruction::LONG_TO_INT:
1547 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1548 break;
1549
buzbee101305f2012-06-28 18:00:56 -07001550 case Instruction::INT_TO_LONG:
1551 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001552 break;
1553
buzbee101305f2012-06-28 18:00:56 -07001554 case Instruction::INT_TO_CHAR:
1555 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1556 greenland::IntrinsicHelper::IntToChar);
1557 break;
1558 case Instruction::INT_TO_BYTE:
1559 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1560 greenland::IntrinsicHelper::IntToByte);
1561 break;
1562 case Instruction::INT_TO_SHORT:
1563 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1564 greenland::IntrinsicHelper::IntToShort);
1565 break;
1566
buzbee76592632012-06-29 15:18:35 -07001567 case Instruction::INT_TO_FLOAT:
1568 case Instruction::LONG_TO_FLOAT:
1569 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001570 break;
1571
buzbee76592632012-06-29 15:18:35 -07001572 case Instruction::INT_TO_DOUBLE:
1573 case Instruction::LONG_TO_DOUBLE:
1574 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001575 break;
1576
buzbee76592632012-06-29 15:18:35 -07001577 case Instruction::FLOAT_TO_DOUBLE:
1578 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001579 break;
1580
buzbee76592632012-06-29 15:18:35 -07001581 case Instruction::DOUBLE_TO_FLOAT:
1582 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001583 break;
1584
1585 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001586 case Instruction::NEG_INT:
1587 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001588 break;
1589
1590 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001591 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001592 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001593 break;
1594
buzbee76592632012-06-29 15:18:35 -07001595 case Instruction::NOT_LONG:
1596 case Instruction::NOT_INT:
1597 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001598 break;
1599
buzbee2cfc6392012-05-07 14:51:40 -07001600 case Instruction::FLOAT_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001601 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2I, rlDest, rlSrc[0]);
1602 break;
1603
buzbee2cfc6392012-05-07 14:51:40 -07001604 case Instruction::DOUBLE_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001605 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2I, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001606 break;
1607
buzbee76592632012-06-29 15:18:35 -07001608 case Instruction::FLOAT_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001609 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2L, rlDest, rlSrc[0]);
1610 break;
1611
buzbee76592632012-06-29 15:18:35 -07001612 case Instruction::DOUBLE_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001613 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2L, rlDest, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001614 break;
1615
1616 case Instruction::CMPL_FLOAT:
1617 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1618 rlDest, rlSrc[0], rlSrc[1]);
1619 break;
1620 case Instruction::CMPG_FLOAT:
1621 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1622 rlDest, rlSrc[0], rlSrc[1]);
1623 break;
1624 case Instruction::CMPL_DOUBLE:
1625 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1626 rlDest, rlSrc[0], rlSrc[1]);
1627 break;
1628 case Instruction::CMPG_DOUBLE:
1629 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1630 rlDest, rlSrc[0], rlSrc[1]);
1631 break;
1632 case Instruction::CMP_LONG:
1633 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1634 rlDest, rlSrc[0], rlSrc[1]);
1635 break;
1636
buzbee76592632012-06-29 15:18:35 -07001637 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001638 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001639 break;
1640
1641 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001642 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001643 break;
buzbee2cfc6392012-05-07 14:51:40 -07001644
1645 default:
buzbee32412962012-06-26 16:27:56 -07001646 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001647 res = true;
1648 }
buzbeeb03f4872012-06-11 15:22:11 -07001649 if (objectDefinition) {
1650 setShadowFrameEntry(cUnit, (llvm::Value*)
1651 cUnit->llvmValues.elemList[rlDest.origSReg]);
1652 }
buzbee2cfc6392012-05-07 14:51:40 -07001653 return res;
1654}
1655
1656/* Extended MIR instructions like PHI */
1657void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1658 llvm::BasicBlock* llvmBB)
1659{
1660
1661 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1662 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001663 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001664 /*
1665 * The Art compiler's Phi nodes only handle 32-bit operands,
1666 * representing wide values using a matched set of Phi nodes
1667 * for the lower and upper halves. In the llvm world, we only
1668 * want a single Phi for wides. Here we will simply discard
1669 * the Phi node representing the high word.
1670 */
1671 if (rlDest.highWord) {
1672 return; // No Phi node - handled via low word
1673 }
1674 int* incoming = (int*)mir->dalvikInsn.vB;
buzbee2cfc6392012-05-07 14:51:40 -07001675 llvm::Type* phiType =
1676 llvmTypeFromLocRec(cUnit, rlDest);
1677 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1678 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1679 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001680 // Don't check width here.
1681 loc = oatGetRawSrc(cUnit, mir, i);
1682 DCHECK_EQ(rlDest.wide, loc.wide);
1683 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1684 DCHECK_EQ(rlDest.fp, loc.fp);
1685 DCHECK_EQ(rlDest.core, loc.core);
1686 DCHECK_EQ(rlDest.ref, loc.ref);
buzbeed1643e42012-09-05 14:06:51 -07001687 SafeMap<unsigned int, unsigned int>::iterator it;
1688 it = cUnit->blockIdMap.find(incoming[i]);
1689 DCHECK(it != cUnit->blockIdMap.end());
buzbee2cfc6392012-05-07 14:51:40 -07001690 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
buzbeed1643e42012-09-05 14:06:51 -07001691 getLLVMBlock(cUnit, it->second));
buzbee2cfc6392012-05-07 14:51:40 -07001692 }
1693 defineValue(cUnit, phi, rlDest.origSReg);
1694 break;
1695 }
1696 case kMirOpCopy: {
1697 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1698 break;
1699 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001700 case kMirOpNop:
1701 if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
1702 (bb->fallThrough == NULL)) {
1703 cUnit->irb->CreateUnreachable();
1704 }
1705 break;
1706
buzbee2cfc6392012-05-07 14:51:40 -07001707#if defined(TARGET_ARM)
1708 case kMirOpFusedCmplFloat:
1709 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1710 break;
1711 case kMirOpFusedCmpgFloat:
1712 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1713 break;
1714 case kMirOpFusedCmplDouble:
1715 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1716 break;
1717 case kMirOpFusedCmpgDouble:
1718 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1719 break;
1720 case kMirOpFusedCmpLong:
1721 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1722 break;
1723#endif
1724 default:
1725 break;
1726 }
1727}
1728
1729void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1730{
1731 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001732 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001733 arrayRef.push_back(cUnit->irb->getInt32(offset));
1734 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1735 cUnit->irb->SetDexOffset(node);
1736}
1737
1738// Attach method info as metadata to special intrinsic
1739void setMethodInfo(CompilationUnit* cUnit)
1740{
1741 // We don't want dex offset on this
1742 cUnit->irb->SetDexOffset(NULL);
1743 greenland::IntrinsicHelper::IntrinsicId id;
1744 id = greenland::IntrinsicHelper::MethodInfo;
1745 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1746 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1747 llvm::SmallVector<llvm::Value*, 2> regInfo;
1748 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1749 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1750 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1751 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1752 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1753 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1754 inst->setMetadata("RegInfo", regInfoNode);
1755 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1756 llvm::SmallVector<llvm::Value*, 50> pmap;
1757 for (int i = 0; i < promoSize; i++) {
1758 PromotionMap* p = &cUnit->promotionMap[i];
1759 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1760 ((p->fpReg & 0xff) << 16) |
1761 ((p->coreReg & 0xff) << 8) |
1762 ((p->fpLocation & 0xf) << 4) |
1763 (p->coreLocation & 0xf);
1764 pmap.push_back(cUnit->irb->getInt32(mapData));
1765 }
1766 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1767 inst->setMetadata("PromotionMap", mapNode);
1768 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1769}
1770
1771/* Handle the content in each basic block */
1772bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1773{
buzbeed1643e42012-09-05 14:06:51 -07001774 if (bb->blockType == kDead) return false;
buzbee2cfc6392012-05-07 14:51:40 -07001775 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
Shih-wei Liao21d28f52012-06-12 05:55:00 -07001776 if (llvmBB != NULL) {
1777 cUnit->irb->SetInsertPoint(llvmBB);
1778 setDexOffset(cUnit, bb->startOffset);
1779 }
buzbee2cfc6392012-05-07 14:51:40 -07001780
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001781 if (cUnit->printMe) {
1782 LOG(INFO) << "................................";
1783 LOG(INFO) << "Block id " << bb->id;
1784 if (llvmBB != NULL) {
1785 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1786 } else {
1787 LOG(INFO) << "llvmBB is NULL";
1788 }
1789 }
1790
buzbee2cfc6392012-05-07 14:51:40 -07001791 if (bb->blockType == kEntryBlock) {
1792 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001793 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1794 cUnit->numDalvikRegisters, true,
1795 kAllocMisc);
1796 for (int i = 0; i < cUnit->numSSARegs; i++) {
1797 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1798 }
1799 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1800 if (canBeRef[i]) {
1801 cUnit->numShadowFrameEntries++;
1802 }
1803 }
1804 if (cUnit->numShadowFrameEntries > 0) {
1805 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1806 cUnit->numShadowFrameEntries, true,
1807 kAllocMisc);
1808 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1809 if (canBeRef[i]) {
1810 cUnit->shadowMap[j++] = i;
1811 }
1812 }
1813 greenland::IntrinsicHelper::IntrinsicId id =
1814 greenland::IntrinsicHelper::AllocaShadowFrame;
1815 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1816 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1817 cUnit->irb->CreateCall(func, entries);
1818 }
buzbee2cfc6392012-05-07 14:51:40 -07001819 } else if (bb->blockType == kExitBlock) {
1820 /*
1821 * Because of the differences between how MIR/LIR and llvm handle exit
1822 * blocks, we won't explicitly covert them. On the llvm-to-lir
1823 * path, it will need to be regenereated.
1824 */
1825 return false;
buzbee6969d502012-06-15 16:40:31 -07001826 } else if (bb->blockType == kExceptionHandling) {
1827 /*
1828 * Because we're deferring null checking, delete the associated empty
1829 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001830 */
1831 llvmBB->eraseFromParent();
1832 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001833 }
1834
1835 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1836
1837 setDexOffset(cUnit, mir->offset);
1838
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001839 int opcode = mir->dalvikInsn.opcode;
1840 Instruction::Format dalvikFormat =
1841 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001842
1843 /* If we're compiling for the debugger, generate an update callout */
1844 if (cUnit->genDebugger) {
1845 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1846 //genDebuggerUpdate(cUnit, mir->offset);
1847 }
1848
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001849 if (opcode == kMirOpCheck) {
1850 // Combine check and work halves of throwing instruction.
1851 MIR* workHalf = mir->meta.throwInsn;
1852 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
1853 opcode = mir->dalvikInsn.opcode;
1854 SSARepresentation* ssaRep = workHalf->ssaRep;
1855 workHalf->ssaRep = mir->ssaRep;
1856 mir->ssaRep = ssaRep;
1857 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1858 if (bb->successorBlockList.blockListType == kCatch) {
1859 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
1860 greenland::IntrinsicHelper::CatchTargets);
1861 llvm::Value* switchKey =
1862 cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
1863 GrowableListIterator iter;
1864 oatGrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
1865 // New basic block to use for work half
1866 llvm::BasicBlock* workBB =
1867 llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
1868 llvm::SwitchInst* sw =
1869 cUnit->irb->CreateSwitch(switchKey, workBB,
1870 bb->successorBlockList.blocks.numUsed);
1871 while (true) {
1872 SuccessorBlockInfo *successorBlockInfo =
1873 (SuccessorBlockInfo *) oatGrowableListIteratorNext(&iter);
1874 if (successorBlockInfo == NULL) break;
1875 llvm::BasicBlock *target =
1876 getLLVMBlock(cUnit, successorBlockInfo->block->id);
1877 int typeIndex = successorBlockInfo->key;
1878 sw->addCase(cUnit->irb->getInt32(typeIndex), target);
1879 }
1880 llvmBB = workBB;
1881 cUnit->irb->SetInsertPoint(llvmBB);
1882 }
1883 }
1884
1885 if (opcode >= kMirOpFirst) {
buzbee2cfc6392012-05-07 14:51:40 -07001886 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1887 continue;
1888 }
1889
1890 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1891 NULL /* labelList */);
1892 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001893 Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001894 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001895 mir->offset, opcode,
buzbee2cfc6392012-05-07 14:51:40 -07001896 Instruction::Name(dalvikOpcode),
1897 dalvikFormat);
1898 }
1899 }
1900
buzbee4be777b2012-07-12 14:38:18 -07001901 if (bb->blockType == kEntryBlock) {
1902 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1903 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001904 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1905 }
1906
1907 return false;
1908}
1909
buzbee4f4dfc72012-07-02 14:54:44 -07001910char remapShorty(char shortyType) {
1911 /*
1912 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1913 * and longs/doubles are represented as a pair of registers. When sub-word
1914 * arguments (and method results) are passed, they are extended to Dalvik
1915 * virtual register containers. Because llvm is picky about type consistency,
1916 * we must either cast the "real" type to 32-bit container multiple Dalvik
1917 * register types, or always use the expanded values.
1918 * Here, we're doing the latter. We map the shorty signature to container
1919 * types (which is valid so long as we always do a real expansion of passed
1920 * arguments and field loads).
1921 */
1922 switch(shortyType) {
1923 case 'Z' : shortyType = 'I'; break;
1924 case 'B' : shortyType = 'I'; break;
1925 case 'S' : shortyType = 'I'; break;
1926 case 'C' : shortyType = 'I'; break;
1927 default: break;
1928 }
1929 return shortyType;
1930}
1931
buzbee2cfc6392012-05-07 14:51:40 -07001932llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1933
1934 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001935 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001936 greenland::kAccurate);
1937
1938 // Get argument type
1939 std::vector<llvm::Type*> args_type;
1940
1941 // method object
1942 args_type.push_back(cUnit->irb->GetJMethodTy());
1943
1944 // Do we have a "this"?
1945 if ((cUnit->access_flags & kAccStatic) == 0) {
1946 args_type.push_back(cUnit->irb->GetJObjectTy());
1947 }
1948
1949 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001950 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001951 greenland::kAccurate));
1952 }
1953
1954 return llvm::FunctionType::get(ret_type, args_type, false);
1955}
1956
1957bool createFunction(CompilationUnit* cUnit) {
1958 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1959 /* with_signature */ false));
1960 llvm::FunctionType* func_type = getFunctionType(cUnit);
1961
1962 if (func_type == NULL) {
1963 return false;
1964 }
1965
1966 cUnit->func = llvm::Function::Create(func_type,
1967 llvm::Function::ExternalLinkage,
1968 func_name, cUnit->module);
1969
1970 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1971 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1972
1973 arg_iter->setName("method");
1974 ++arg_iter;
1975
1976 int startSReg = cUnit->numRegs;
1977
1978 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1979 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1980 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1981 }
1982
1983 return true;
1984}
1985
1986bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1987{
1988 // Skip the exit block
buzbeed1643e42012-09-05 14:06:51 -07001989 if ((bb->blockType == kDead) ||(bb->blockType == kExitBlock)) {
buzbee2cfc6392012-05-07 14:51:40 -07001990 cUnit->idToBlockMap.Put(bb->id, NULL);
1991 } else {
1992 int offset = bb->startOffset;
1993 bool entryBlock = (bb->blockType == kEntryBlock);
1994 llvm::BasicBlock* llvmBB =
1995 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
buzbee8320f382012-09-11 16:29:42 -07001996 StringPrintf(kLabelFormat, bb->catchEntry ? kCatchBlock :
1997 kNormalBlock, offset, bb->id), cUnit->func);
buzbee2cfc6392012-05-07 14:51:40 -07001998 if (entryBlock) {
1999 cUnit->entryBB = llvmBB;
2000 cUnit->placeholderBB =
2001 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
2002 cUnit->func);
2003 }
2004 cUnit->idToBlockMap.Put(bb->id, llvmBB);
2005 }
2006 return false;
2007}
2008
2009
2010/*
2011 * Convert MIR to LLVM_IR
2012 * o For each ssa name, create LLVM named value. Type these
2013 * appropriately, and ignore high half of wide and double operands.
2014 * o For each MIR basic block, create an LLVM basic block.
2015 * o Iterate through the MIR a basic block at a time, setting arguments
2016 * to recovered ssa name.
2017 */
2018void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
2019{
2020 initIR(cUnit);
2021 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
2022
2023 // Create the function
2024 createFunction(cUnit);
2025
2026 // Create an LLVM basic block for each MIR block in dfs preorder
2027 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
2028 kPreOrderDFSTraversal, false /* isIterative */);
2029 /*
2030 * Create an llvm named value for each MIR SSA name. Note: we'll use
2031 * placeholders for all non-argument values (because we haven't seen
2032 * the definition yet).
2033 */
2034 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2035 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2036 arg_iter++; /* Skip path method */
2037 for (int i = 0; i < cUnit->numSSARegs; i++) {
2038 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07002039 RegLocation rlTemp = cUnit->regLocation[i];
2040 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07002041 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
2042 } else if ((i < cUnit->numRegs) ||
2043 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07002044 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
2045 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07002046 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
2047 val->setName(llvmSSAName(cUnit, i));
buzbee2cfc6392012-05-07 14:51:40 -07002048 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
buzbee2cfc6392012-05-07 14:51:40 -07002049 } else {
2050 // Recover previously-created argument values
2051 llvm::Value* argVal = arg_iter++;
2052 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
2053 }
2054 }
buzbee2cfc6392012-05-07 14:51:40 -07002055
2056 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
2057 kPreOrderDFSTraversal, false /* Iterative */);
2058
buzbee4be777b2012-07-12 14:38:18 -07002059 /*
2060 * In a few rare cases of verification failure, the verifier will
2061 * replace one or more Dalvik opcodes with the special
2062 * throw-verification-failure opcode. This can leave the SSA graph
2063 * in an invalid state, as definitions may be lost, while uses retained.
2064 * To work around this problem, we insert placeholder definitions for
2065 * all Dalvik SSA regs in the "placeholder" block. Here, after
2066 * bitcode conversion is complete, we examine those placeholder definitions
2067 * and delete any with no references (which normally is all of them).
2068 *
2069 * If any definitions remain, we link the placeholder block into the
2070 * CFG. Otherwise, it is deleted.
2071 */
2072 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
2073 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
2074 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2075 DCHECK(inst != NULL);
2076 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2077 DCHECK(val != NULL);
2078 if (val->getNumUses() == 0) {
2079 inst->eraseFromParent();
2080 }
2081 }
2082 setDexOffset(cUnit, 0);
2083 if (cUnit->placeholderBB->empty()) {
2084 cUnit->placeholderBB->eraseFromParent();
2085 } else {
2086 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2087 cUnit->irb->CreateBr(cUnit->entryTargetBB);
2088 cUnit->entryTargetBB = cUnit->placeholderBB;
2089 }
2090 cUnit->irb->SetInsertPoint(cUnit->entryBB);
2091 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07002092
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002093 if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
2094 if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
2095 LOG(INFO) << "Bitcode verification FAILED for "
2096 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
2097 << " of size " << cUnit->insnsSize;
2098 cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
2099 }
2100 }
buzbee2cfc6392012-05-07 14:51:40 -07002101
buzbeead8f15e2012-06-18 14:49:45 -07002102 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
2103 // Write bitcode to file
2104 std::string errmsg;
2105 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
2106 oatReplaceSpecialChars(fname);
2107 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07002108 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002109
buzbeead8f15e2012-06-18 14:49:45 -07002110 llvm::OwningPtr<llvm::tool_output_file> out_file(
2111 new llvm::tool_output_file(fname.c_str(), errmsg,
2112 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002113
buzbeead8f15e2012-06-18 14:49:45 -07002114 if (!errmsg.empty()) {
2115 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2116 }
2117
2118 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2119 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002120 }
buzbee2cfc6392012-05-07 14:51:40 -07002121}
2122
2123RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2124 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002125 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002126 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2127 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002128 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002129 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002130 // FIXME: need to be more robust, handle FP and be in a position to
2131 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002132 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2133 memset(&res, 0, sizeof(res));
2134 res.location = kLocPhysReg;
2135 res.lowReg = oatAllocTemp(cUnit);
2136 res.home = true;
2137 res.sRegLow = INVALID_SREG;
2138 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002139 llvm::Type* ty = val->getType();
2140 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2141 (ty == cUnit->irb->getDoubleTy()));
2142 if (res.wide) {
2143 res.highReg = oatAllocTemp(cUnit);
2144 }
buzbee4f1181f2012-06-22 13:52:12 -07002145 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002146 } else {
2147 DCHECK_EQ(valName[0], 'v');
2148 int baseSReg = INVALID_SREG;
2149 sscanf(valName.c_str(), "v%d_", &baseSReg);
2150 res = cUnit->regLocation[baseSReg];
2151 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002152 }
2153 } else {
2154 res = it->second;
2155 }
2156 return res;
2157}
2158
2159Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2160{
2161 Instruction::Code res = Instruction::NOP;
2162 if (isWide) {
2163 switch(op) {
2164 case kOpAdd: res = Instruction::ADD_LONG; break;
2165 case kOpSub: res = Instruction::SUB_LONG; break;
2166 case kOpMul: res = Instruction::MUL_LONG; break;
2167 case kOpDiv: res = Instruction::DIV_LONG; break;
2168 case kOpRem: res = Instruction::REM_LONG; break;
2169 case kOpAnd: res = Instruction::AND_LONG; break;
2170 case kOpOr: res = Instruction::OR_LONG; break;
2171 case kOpXor: res = Instruction::XOR_LONG; break;
2172 case kOpLsl: res = Instruction::SHL_LONG; break;
2173 case kOpLsr: res = Instruction::USHR_LONG; break;
2174 case kOpAsr: res = Instruction::SHR_LONG; break;
2175 default: LOG(FATAL) << "Unexpected OpKind " << op;
2176 }
2177 } else if (isConst){
2178 switch(op) {
2179 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2180 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2181 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2182 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2183 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2184 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2185 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2186 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2187 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2188 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2189 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2190 default: LOG(FATAL) << "Unexpected OpKind " << op;
2191 }
2192 } else {
2193 switch(op) {
2194 case kOpAdd: res = Instruction::ADD_INT; break;
2195 case kOpSub: res = Instruction::SUB_INT; break;
2196 case kOpMul: res = Instruction::MUL_INT; break;
2197 case kOpDiv: res = Instruction::DIV_INT; break;
2198 case kOpRem: res = Instruction::REM_INT; break;
2199 case kOpAnd: res = Instruction::AND_INT; break;
2200 case kOpOr: res = Instruction::OR_INT; break;
2201 case kOpXor: res = Instruction::XOR_INT; break;
2202 case kOpLsl: res = Instruction::SHL_INT; break;
2203 case kOpLsr: res = Instruction::USHR_INT; break;
2204 case kOpAsr: res = Instruction::SHR_INT; break;
2205 default: LOG(FATAL) << "Unexpected OpKind " << op;
2206 }
2207 }
2208 return res;
2209}
2210
buzbee4f1181f2012-06-22 13:52:12 -07002211Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2212{
2213 Instruction::Code res = Instruction::NOP;
2214 if (isWide) {
2215 switch(op) {
2216 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2217 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2218 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2219 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2220 case kOpRem: res = Instruction::REM_DOUBLE; break;
2221 default: LOG(FATAL) << "Unexpected OpKind " << op;
2222 }
2223 } else {
2224 switch(op) {
2225 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2226 case kOpSub: res = Instruction::SUB_FLOAT; break;
2227 case kOpMul: res = Instruction::MUL_FLOAT; break;
2228 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2229 case kOpRem: res = Instruction::REM_FLOAT; break;
2230 default: LOG(FATAL) << "Unexpected OpKind " << op;
2231 }
2232 }
2233 return res;
2234}
2235
2236void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2237{
2238 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002239 /*
2240 * Normally, we won't ever generate an FP operation with an immediate
2241 * operand (not supported in Dex instruction set). However, the IR builder
2242 * may insert them - in particular for createNegFP. Recognize this case
2243 * and deal with it.
2244 */
2245 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2246 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2247 DCHECK(op2C == NULL);
2248 if ((op1C != NULL) && (op == kOpSub)) {
2249 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2250 if (rlDest.wide) {
2251 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2252 } else {
2253 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2254 }
buzbee4f1181f2012-06-22 13:52:12 -07002255 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002256 DCHECK(op1C == NULL);
2257 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2258 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2259 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2260 if (rlDest.wide) {
2261 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2262 } else {
2263 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2264 }
buzbee4f1181f2012-06-22 13:52:12 -07002265 }
2266}
2267
buzbee101305f2012-06-28 18:00:56 -07002268void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2269 Instruction::Code opcode)
2270{
2271 RegLocation rlDest = getLoc(cUnit, inst);
2272 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2273 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2274}
2275
buzbee76592632012-06-29 15:18:35 -07002276void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2277{
2278 RegLocation rlDest = getLoc(cUnit, inst);
2279 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2280 Instruction::Code opcode;
2281 if (rlDest.wide) {
2282 if (rlSrc.wide) {
2283 opcode = Instruction::LONG_TO_DOUBLE;
2284 } else {
2285 opcode = Instruction::INT_TO_DOUBLE;
2286 }
2287 } else {
2288 if (rlSrc.wide) {
2289 opcode = Instruction::LONG_TO_FLOAT;
2290 } else {
2291 opcode = Instruction::INT_TO_FLOAT;
2292 }
2293 }
2294 genConversion(cUnit, opcode, rlDest, rlSrc);
2295}
2296
TDYa1274ec8ccd2012-08-11 07:04:57 -07002297void cvtFPToInt(CompilationUnit* cUnit, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002298{
TDYa1274ec8ccd2012-08-11 07:04:57 -07002299 RegLocation rlDest = getLoc(cUnit, call_inst);
2300 RegLocation rlSrc = getLoc(cUnit, call_inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002301 Instruction::Code opcode;
2302 if (rlDest.wide) {
2303 if (rlSrc.wide) {
2304 opcode = Instruction::DOUBLE_TO_LONG;
2305 } else {
2306 opcode = Instruction::FLOAT_TO_LONG;
2307 }
2308 } else {
2309 if (rlSrc.wide) {
2310 opcode = Instruction::DOUBLE_TO_INT;
2311 } else {
2312 opcode = Instruction::FLOAT_TO_INT;
2313 }
2314 }
2315 genConversion(cUnit, opcode, rlDest, rlSrc);
2316}
2317
2318void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2319{
2320 RegLocation rlDest = getLoc(cUnit, inst);
2321 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2322 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2323}
2324
2325void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2326{
2327 RegLocation rlDest = getLoc(cUnit, inst);
2328 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2329 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2330 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2331 storeValue(cUnit, rlDest, rlSrc);
2332}
2333
2334void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2335{
2336 RegLocation rlDest = getLoc(cUnit, inst);
2337 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2338 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2339}
2340
2341
buzbee101305f2012-06-28 18:00:56 -07002342void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2343{
2344 // TODO: evaluate src/tgt types and add general support for more than int to long
2345 RegLocation rlDest = getLoc(cUnit, inst);
2346 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2347 DCHECK(rlDest.wide);
2348 DCHECK(!rlSrc.wide);
2349 DCHECK(!rlDest.fp);
2350 DCHECK(!rlSrc.fp);
2351 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2352 if (rlSrc.location == kLocPhysReg) {
2353 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2354 } else {
2355 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2356 }
2357 if (isSigned) {
2358 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2359 } else {
2360 loadConstant(cUnit, rlResult.highReg, 0);
2361 }
2362 storeValueWide(cUnit, rlDest, rlResult);
2363}
2364
buzbee2cfc6392012-05-07 14:51:40 -07002365void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2366{
2367 RegLocation rlDest = getLoc(cUnit, inst);
2368 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002369 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002370 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2371 if ((op == kOpSub) && (lhsImm != NULL)) {
2372 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002373 if (rlSrc1.wide) {
2374 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2375 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2376 } else {
2377 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2378 lhsImm->getSExtValue());
2379 }
buzbee4f1181f2012-06-22 13:52:12 -07002380 return;
2381 }
2382 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002383 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2384 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002385 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2386 if (!rlDest.wide && (constRhs != NULL)) {
buzbee2cfc6392012-05-07 14:51:40 -07002387 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
buzbee9a2487f2012-07-26 14:01:13 -07002388 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002389 } else {
2390 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002391 RegLocation rlSrc2;
2392 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002393 // ir_builder converts NOT_LONG to xor src, -1. Restore
2394 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2395 DCHECK_EQ(-1L, constRhs->getSExtValue());
2396 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002397 rlSrc2 = rlSrc1;
2398 } else {
2399 rlSrc2 = getLoc(cUnit, rhs);
2400 }
buzbee2cfc6392012-05-07 14:51:40 -07002401 if (rlDest.wide) {
2402 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2403 } else {
2404 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2405 }
2406 }
2407}
2408
buzbee2a83e8f2012-07-13 16:42:30 -07002409void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2410 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002411{
buzbee2a83e8f2012-07-13 16:42:30 -07002412 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2413 RegLocation rlDest = getLoc(cUnit, callInst);
2414 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2415 llvm::Value* rhs = callInst->getArgOperand(1);
2416 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2417 DCHECK(!rlDest.wide);
2418 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002419 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002420 RegLocation rlShift = getLoc(cUnit, rhs);
2421 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2422 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2423 } else {
2424 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2425 }
buzbee101305f2012-06-28 18:00:56 -07002426 }
2427}
2428
buzbee2cfc6392012-05-07 14:51:40 -07002429void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2430{
2431 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2432 DCHECK(brInst != NULL);
2433 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2434 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2435 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2436}
2437
2438void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2439{
2440 // Nop - these have already been processed
2441}
2442
2443void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2444{
2445 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2446 llvm::Value* retVal = retInst->getReturnValue();
2447 if (retVal != NULL) {
2448 RegLocation rlSrc = getLoc(cUnit, retVal);
2449 if (rlSrc.wide) {
2450 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2451 } else {
2452 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2453 }
2454 }
2455 genExitSequence(cUnit);
2456}
2457
2458ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2459{
2460 ConditionCode res = kCondAl;
2461 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002462 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002463 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2464 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2465 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002466 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002467 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002468 default: LOG(FATAL) << "Unexpected llvm condition";
2469 }
2470 return res;
2471}
2472
2473void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2474{
2475 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2476 UNIMPLEMENTED(FATAL);
2477}
2478
2479void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2480 llvm::BranchInst* brInst)
2481{
2482 // Get targets
2483 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2484 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2485 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2486 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2487 // Get comparison operands
2488 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2489 ConditionCode cond = getCond(iCmpInst->getPredicate());
2490 llvm::Value* lhs = iCmpInst->getOperand(0);
2491 // Not expecting a constant as 1st operand
2492 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2493 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2494 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2495 llvm::Value* rhs = inst->getOperand(1);
2496#if defined(TARGET_MIPS)
2497 // Compare and branch in one shot
2498 (void)taken;
2499 (void)cond;
2500 (void)rhs;
2501 UNIMPLEMENTED(FATAL);
2502#else
2503 //Compare, then branch
2504 // TODO: handle fused CMP_LONG/IF_xxZ case
2505 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2506 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002507 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2508 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002509 } else {
2510 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2511 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2512 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2513 }
2514 opCondBranch(cUnit, cond, taken);
2515#endif
2516 // Fallthrough
2517 opUnconditionalBranch(cUnit, fallThrough);
2518}
2519
2520void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2521 llvm::Function* callee)
2522{
2523 UNIMPLEMENTED(FATAL);
2524}
2525
buzbee2cfc6392012-05-07 14:51:40 -07002526void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2527{
buzbee4f1181f2012-06-22 13:52:12 -07002528 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002529 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2530 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002531 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2532 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002533 if (rlSrc.wide) {
2534 storeValueWide(cUnit, rlDest, rlSrc);
2535 } else {
2536 storeValue(cUnit, rlDest, rlSrc);
2537 }
2538}
2539
2540// Note: Immediate arg is a ConstantInt regardless of result type
2541void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2542{
buzbee4f1181f2012-06-22 13:52:12 -07002543 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002544 llvm::ConstantInt* src =
2545 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2546 uint64_t immval = src->getZExtValue();
2547 RegLocation rlDest = getLoc(cUnit, callInst);
2548 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2549 if (rlDest.wide) {
2550 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2551 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2552 storeValueWide(cUnit, rlDest, rlResult);
2553 } else {
2554 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2555 storeValue(cUnit, rlDest, rlResult);
2556 }
2557}
2558
buzbee101305f2012-06-28 18:00:56 -07002559void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2560 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002561{
buzbee4f1181f2012-06-22 13:52:12 -07002562 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002563 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002564 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002565 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002566 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002567 if (isString) {
2568 genConstString(cUnit, index, rlDest);
2569 } else {
2570 genConstClass(cUnit, index, rlDest);
2571 }
2572}
2573
2574void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2575{
2576 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2577 llvm::ConstantInt* offsetVal =
2578 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2579 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2580 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002581}
2582
buzbee4f1181f2012-06-22 13:52:12 -07002583void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2584{
buzbee32412962012-06-26 16:27:56 -07002585 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002586 llvm::ConstantInt* typeIdxVal =
2587 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2588 uint32_t typeIdx = typeIdxVal->getZExtValue();
2589 RegLocation rlDest = getLoc(cUnit, callInst);
2590 genNewInstance(cUnit, typeIdx, rlDest);
2591}
2592
buzbee8fa0fda2012-06-27 15:44:52 -07002593void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2594{
2595 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2596 llvm::ConstantInt* typeIdxVal =
2597 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2598 uint32_t typeIdx = typeIdxVal->getZExtValue();
2599 llvm::Value* len = callInst->getArgOperand(1);
2600 RegLocation rlLen = getLoc(cUnit, len);
2601 RegLocation rlDest = getLoc(cUnit, callInst);
2602 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2603}
2604
2605void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2606{
2607 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2608 llvm::ConstantInt* typeIdxVal =
2609 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2610 uint32_t typeIdx = typeIdxVal->getZExtValue();
2611 llvm::Value* src = callInst->getArgOperand(1);
2612 RegLocation rlSrc = getLoc(cUnit, src);
2613 RegLocation rlDest = getLoc(cUnit, callInst);
2614 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2615}
2616
buzbee32412962012-06-26 16:27:56 -07002617void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2618{
2619 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2620 llvm::Value* src = callInst->getArgOperand(0);
2621 RegLocation rlSrc = getLoc(cUnit, src);
2622 genThrow(cUnit, rlSrc);
2623}
2624
buzbee8fa0fda2012-06-27 15:44:52 -07002625void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2626 llvm::CallInst* callInst)
2627{
2628 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2629 llvm::ConstantInt* optFlags =
2630 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2631 llvm::Value* src = callInst->getArgOperand(1);
2632 RegLocation rlSrc = getLoc(cUnit, src);
2633 if (isEnter) {
2634 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2635 } else {
2636 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2637 }
2638}
2639
buzbee76592632012-06-29 15:18:35 -07002640void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002641{
2642 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2643 llvm::ConstantInt* optFlags =
2644 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2645 llvm::Value* src = callInst->getArgOperand(1);
2646 RegLocation rlSrc = getLoc(cUnit, src);
2647 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2648 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2649 RegLocation rlDest = getLoc(cUnit, callInst);
2650 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2651 int lenOffset = Array::LengthOffset().Int32Value();
2652 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2653 storeValue(cUnit, rlDest, rlResult);
2654}
2655
buzbee32412962012-06-26 16:27:56 -07002656void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2657{
2658 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
2659 int exOffset = Thread::ExceptionOffset().Int32Value();
2660 RegLocation rlDest = getLoc(cUnit, callInst);
2661 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2662#if defined(TARGET_X86)
2663 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
2664 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
2665#else
2666 int resetReg = oatAllocTemp(cUnit);
2667 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
2668 loadConstant(cUnit, resetReg, 0);
2669 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
2670 oatFreeTemp(cUnit, resetReg);
2671#endif
2672 storeValue(cUnit, rlDest, rlResult);
2673}
2674
buzbee4f1181f2012-06-22 13:52:12 -07002675void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2676 bool isObject)
2677{
buzbee32412962012-06-26 16:27:56 -07002678 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002679 llvm::ConstantInt* typeIdxVal =
2680 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2681 uint32_t typeIdx = typeIdxVal->getZExtValue();
2682 RegLocation rlDest = getLoc(cUnit, callInst);
2683 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2684}
2685
buzbee8fa0fda2012-06-27 15:44:52 -07002686void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2687 bool isObject)
2688{
2689 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2690 llvm::ConstantInt* typeIdxVal =
2691 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2692 uint32_t typeIdx = typeIdxVal->getZExtValue();
2693 llvm::Value* src = callInst->getArgOperand(1);
2694 RegLocation rlSrc = getLoc(cUnit, src);
2695 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2696}
2697
2698void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2699 int scale)
2700{
2701 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2702 llvm::ConstantInt* optFlags =
2703 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2704 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2705 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2706 RegLocation rlDest = getLoc(cUnit, callInst);
2707 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2708 rlDest, scale);
2709}
2710
2711void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002712 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002713{
2714 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2715 llvm::ConstantInt* optFlags =
2716 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2717 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2718 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2719 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002720 if (isObject) {
2721 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2722 rlSrc, scale);
2723 } else {
2724 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2725 rlSrc, scale);
2726 }
2727}
2728
2729void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2730{
2731 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2732}
2733
2734void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2735 OpSize size, int scale)
2736{
2737 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002738}
2739
buzbee101305f2012-06-28 18:00:56 -07002740void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2741 bool isWide, bool isObj)
2742{
2743 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2744 llvm::ConstantInt* optFlags =
2745 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2746 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2747 llvm::ConstantInt* fieldIdx =
2748 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2749 RegLocation rlDest = getLoc(cUnit, callInst);
2750 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2751 size, rlDest, rlObj, isWide, isObj);
2752}
2753
2754void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2755 bool isWide, bool isObj)
2756{
2757 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2758 llvm::ConstantInt* optFlags =
2759 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2760 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2761 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2762 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002763 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002764 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2765 size, rlSrc, rlObj, isWide, isObj);
2766}
2767
2768void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2769{
2770 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2771 llvm::ConstantInt* typeIdx =
2772 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2773 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2774 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2775}
2776
buzbee76592632012-06-29 15:18:35 -07002777void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2778 Instruction::Code opcode)
2779{
2780 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2781 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2782 RegLocation rlDest = getLoc(cUnit, callInst);
2783 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2784}
2785
2786void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2787{
2788 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2789 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2790 RegLocation rlDest = getLoc(cUnit, callInst);
2791 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2792}
2793
buzbeef58c12c2012-07-03 15:06:29 -07002794void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2795{
2796 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2797 DCHECK(swInst != NULL);
2798 llvm::Value* testVal = swInst->getCondition();
2799 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2800 DCHECK(tableOffsetNode != NULL);
2801 llvm::ConstantInt* tableOffsetValue =
2802 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2803 int32_t tableOffset = tableOffsetValue->getSExtValue();
2804 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeea1da8a52012-07-09 14:00:21 -07002805 const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2806 u2 tableMagic = *table;
2807 if (tableMagic == 0x100) {
2808 genPackedSwitch(cUnit, tableOffset, rlSrc);
2809 } else {
2810 DCHECK_EQ(tableMagic, 0x200);
2811 genSparseSwitch(cUnit, tableOffset, rlSrc);
2812 }
buzbeef58c12c2012-07-03 15:06:29 -07002813}
2814
buzbee6969d502012-06-15 16:40:31 -07002815void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002816 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002817{
2818 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2819 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002820 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002821 info->result.location = kLocInvalid;
2822 } else {
2823 info->result = getLoc(cUnit, callInst);
2824 }
2825 llvm::ConstantInt* invokeTypeVal =
2826 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2827 llvm::ConstantInt* methodIndexVal =
2828 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2829 llvm::ConstantInt* optFlagsVal =
2830 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2831 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2832 info->index = methodIndexVal->getZExtValue();
2833 info->optFlags = optFlagsVal->getZExtValue();
2834 info->offset = cUnit->currentDalvikOffset;
2835
buzbee6969d502012-06-15 16:40:31 -07002836 // Count the argument words, and then build argument array.
2837 info->numArgWords = 0;
2838 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2839 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2840 info->numArgWords += tLoc.wide ? 2 : 1;
2841 }
2842 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2843 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2844 // Now, fill in the location records, synthesizing high loc of wide vals
2845 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002846 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002847 if (info->args[next].wide) {
2848 next++;
2849 // TODO: Might make sense to mark this as an invalid loc
2850 info->args[next].origSReg = info->args[next-1].origSReg+1;
2851 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2852 }
2853 next++;
2854 }
buzbee4f4dfc72012-07-02 14:54:44 -07002855 // TODO - rework such that we no longer need isRange
2856 info->isRange = (info->numArgWords > 5);
2857
buzbee76592632012-06-29 15:18:35 -07002858 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002859 genFilledNewArray(cUnit, info);
2860 } else {
2861 genInvoke(cUnit, info);
2862 }
buzbee6969d502012-06-15 16:40:31 -07002863}
2864
buzbeead8f15e2012-06-18 14:49:45 -07002865/* Look up the RegLocation associated with a Value. Must already be defined */
2866RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2867{
2868 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2869 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2870 return it->second;
2871}
2872
buzbee2cfc6392012-05-07 14:51:40 -07002873bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2874{
buzbee0967a252012-09-14 10:43:54 -07002875 while (cUnit->llvmBlocks.find(bb) == cUnit->llvmBlocks.end()) {
2876 llvm::BasicBlock* nextBB = NULL;
2877 cUnit->llvmBlocks.insert(bb);
2878 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2879 // Define the starting label
2880 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2881 // Extract the type and starting offset from the block's name
2882 char blockType = kNormalBlock;
2883 if (!isEntry) {
2884 const char* blockName = bb->getName().str().c_str();
2885 int dummy;
2886 sscanf(blockName, kLabelFormat, &blockType, &blockLabel->operands[0], &dummy);
2887 cUnit->currentDalvikOffset = blockLabel->operands[0];
2888 } else {
2889 cUnit->currentDalvikOffset = 0;
2890 }
2891 // Set the label kind
2892 blockLabel->opcode = kPseudoNormalBlockLabel;
2893 // Insert the label
2894 oatAppendLIR(cUnit, blockLabel);
buzbee2cfc6392012-05-07 14:51:40 -07002895
buzbee0967a252012-09-14 10:43:54 -07002896 LIR* headLIR = NULL;
buzbee8320f382012-09-11 16:29:42 -07002897
buzbee0967a252012-09-14 10:43:54 -07002898 if (blockType == kCatchBlock) {
2899 headLIR = newLIR0(cUnit, kPseudoSafepointPC);
2900 }
buzbee8320f382012-09-11 16:29:42 -07002901
buzbee0967a252012-09-14 10:43:54 -07002902 // Free temp registers and reset redundant store tracking */
2903 oatResetRegPool(cUnit);
2904 oatResetDefTracking(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002905
buzbee0967a252012-09-14 10:43:54 -07002906 //TODO: restore oat incoming liveness optimization
2907 oatClobberAllRegs(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002908
buzbee0967a252012-09-14 10:43:54 -07002909 if (isEntry) {
2910 RegLocation* argLocs = (RegLocation*)
2911 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2912 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2913 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2914 // Skip past Method*
2915 it++;
2916 for (unsigned i = 0; it != it_end; ++it) {
2917 llvm::Value* val = it;
2918 argLocs[i++] = valToLoc(cUnit, val);
2919 llvm::Type* ty = val->getType();
2920 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2921 argLocs[i] = argLocs[i-1];
2922 argLocs[i].lowReg = argLocs[i].highReg;
2923 argLocs[i].origSReg++;
2924 argLocs[i].sRegLow = INVALID_SREG;
2925 argLocs[i].highWord = true;
2926 i++;
2927 }
2928 }
2929 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
2930 }
2931
2932 // Visit all of the instructions in the block
2933 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2934 llvm::Instruction* inst = it;
2935 llvm::BasicBlock::iterator nextIt = ++it;
2936 // Extract the Dalvik offset from the instruction
2937 uint32_t opcode = inst->getOpcode();
2938 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2939 if (dexOffsetNode != NULL) {
2940 llvm::ConstantInt* dexOffsetValue =
2941 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2942 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2943 }
2944
2945 oatResetRegPool(cUnit);
2946 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2947 oatClobberAllRegs(cUnit);
2948 }
2949
2950 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2951 oatResetDefTracking(cUnit);
2952 }
2953
2954 #ifndef NDEBUG
2955 /* Reset temp tracking sanity check */
2956 cUnit->liveSReg = INVALID_SREG;
2957 #endif
2958
2959 // TODO: use llvm opcode name here instead of "boundary" if verbose
2960 LIR* boundaryLIR = markBoundary(cUnit, cUnit->currentDalvikOffset, "boundary");
2961
2962 /* Remember the first LIR for thisl block*/
2963 if (headLIR == NULL) {
2964 headLIR = boundaryLIR;
2965 headLIR->defMask = ENCODE_ALL;
2966 }
2967
2968 switch(opcode) {
2969
2970 case llvm::Instruction::ICmp: {
2971 llvm::Instruction* nextInst = nextIt;
2972 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2973 if (brInst != NULL /* and... */) {
2974 cvtICmpBr(cUnit, inst, brInst);
2975 ++it;
2976 } else {
2977 cvtICmp(cUnit, inst);
2978 }
2979 }
2980 break;
2981
2982 case llvm::Instruction::Call: {
2983 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2984 llvm::Function* callee = callInst->getCalledFunction();
2985 greenland::IntrinsicHelper::IntrinsicId id =
2986 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2987 switch (id) {
2988 case greenland::IntrinsicHelper::AllocaShadowFrame:
2989 case greenland::IntrinsicHelper::SetShadowFrameEntry:
2990 case greenland::IntrinsicHelper::PopShadowFrame:
2991 // Ignore shadow frame stuff for quick compiler
2992 break;
2993 case greenland::IntrinsicHelper::CopyInt:
2994 case greenland::IntrinsicHelper::CopyObj:
2995 case greenland::IntrinsicHelper::CopyFloat:
2996 case greenland::IntrinsicHelper::CopyLong:
2997 case greenland::IntrinsicHelper::CopyDouble:
2998 cvtCopy(cUnit, callInst);
2999 break;
3000 case greenland::IntrinsicHelper::ConstInt:
3001 case greenland::IntrinsicHelper::ConstObj:
3002 case greenland::IntrinsicHelper::ConstLong:
3003 case greenland::IntrinsicHelper::ConstFloat:
3004 case greenland::IntrinsicHelper::ConstDouble:
3005 cvtConst(cUnit, callInst);
3006 break;
3007 case greenland::IntrinsicHelper::DivInt:
3008 case greenland::IntrinsicHelper::DivLong:
3009 cvtBinOp(cUnit, kOpDiv, inst);
3010 break;
3011 case greenland::IntrinsicHelper::RemInt:
3012 case greenland::IntrinsicHelper::RemLong:
3013 cvtBinOp(cUnit, kOpRem, inst);
3014 break;
3015 case greenland::IntrinsicHelper::MethodInfo:
3016 // Already dealt with - just ignore it here.
3017 break;
3018 case greenland::IntrinsicHelper::CheckSuspend:
3019 genSuspendTest(cUnit, 0 /* optFlags already applied */);
3020 break;
3021 case greenland::IntrinsicHelper::HLInvokeObj:
3022 case greenland::IntrinsicHelper::HLInvokeFloat:
3023 case greenland::IntrinsicHelper::HLInvokeDouble:
3024 case greenland::IntrinsicHelper::HLInvokeLong:
3025 case greenland::IntrinsicHelper::HLInvokeInt:
3026 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
3027 break;
3028 case greenland::IntrinsicHelper::HLInvokeVoid:
3029 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
3030 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003031 case greenland::IntrinsicHelper::HLFilledNewArray:
buzbee0967a252012-09-14 10:43:54 -07003032 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
3033 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003034 case greenland::IntrinsicHelper::HLFillArrayData:
buzbee0967a252012-09-14 10:43:54 -07003035 cvtFillArrayData(cUnit, callInst);
3036 break;
3037 case greenland::IntrinsicHelper::ConstString:
3038 cvtConstObject(cUnit, callInst, true /* isString */);
3039 break;
3040 case greenland::IntrinsicHelper::ConstClass:
3041 cvtConstObject(cUnit, callInst, false /* isString */);
3042 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003043 case greenland::IntrinsicHelper::HLCheckCast:
buzbee0967a252012-09-14 10:43:54 -07003044 cvtCheckCast(cUnit, callInst);
3045 break;
3046 case greenland::IntrinsicHelper::NewInstance:
3047 cvtNewInstance(cUnit, callInst);
3048 break;
3049 case greenland::IntrinsicHelper::HLSgetObject:
3050 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
3051 break;
3052 case greenland::IntrinsicHelper::HLSget:
3053 case greenland::IntrinsicHelper::HLSgetFloat:
3054 case greenland::IntrinsicHelper::HLSgetBoolean:
3055 case greenland::IntrinsicHelper::HLSgetByte:
3056 case greenland::IntrinsicHelper::HLSgetChar:
3057 case greenland::IntrinsicHelper::HLSgetShort:
3058 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
3059 break;
3060 case greenland::IntrinsicHelper::HLSgetWide:
3061 case greenland::IntrinsicHelper::HLSgetDouble:
3062 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
3063 break;
3064 case greenland::IntrinsicHelper::HLSput:
3065 case greenland::IntrinsicHelper::HLSputFloat:
3066 case greenland::IntrinsicHelper::HLSputBoolean:
3067 case greenland::IntrinsicHelper::HLSputByte:
3068 case greenland::IntrinsicHelper::HLSputChar:
3069 case greenland::IntrinsicHelper::HLSputShort:
3070 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
3071 break;
3072 case greenland::IntrinsicHelper::HLSputWide:
3073 case greenland::IntrinsicHelper::HLSputDouble:
3074 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
3075 break;
3076 case greenland::IntrinsicHelper::HLSputObject:
3077 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
3078 break;
3079 case greenland::IntrinsicHelper::GetException:
3080 cvtMoveException(cUnit, callInst);
3081 break;
TDYa127f71bf5a2012-07-29 20:09:52 -07003082 case greenland::IntrinsicHelper::HLThrowException:
buzbee0967a252012-09-14 10:43:54 -07003083 cvtThrow(cUnit, callInst);
3084 break;
3085 case greenland::IntrinsicHelper::MonitorEnter:
3086 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
3087 break;
3088 case greenland::IntrinsicHelper::MonitorExit:
3089 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
3090 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003091 case greenland::IntrinsicHelper::OptArrayLength:
buzbee0967a252012-09-14 10:43:54 -07003092 cvtArrayLength(cUnit, callInst);
3093 break;
3094 case greenland::IntrinsicHelper::NewArray:
3095 cvtNewArray(cUnit, callInst);
3096 break;
3097 case greenland::IntrinsicHelper::InstanceOf:
3098 cvtInstanceOf(cUnit, callInst);
3099 break;
3100
3101 case greenland::IntrinsicHelper::HLArrayGet:
3102 case greenland::IntrinsicHelper::HLArrayGetObject:
3103 case greenland::IntrinsicHelper::HLArrayGetFloat:
3104 cvtAget(cUnit, callInst, kWord, 2);
3105 break;
3106 case greenland::IntrinsicHelper::HLArrayGetWide:
3107 case greenland::IntrinsicHelper::HLArrayGetDouble:
3108 cvtAget(cUnit, callInst, kLong, 3);
3109 break;
3110 case greenland::IntrinsicHelper::HLArrayGetBoolean:
3111 cvtAget(cUnit, callInst, kUnsignedByte, 0);
3112 break;
3113 case greenland::IntrinsicHelper::HLArrayGetByte:
3114 cvtAget(cUnit, callInst, kSignedByte, 0);
3115 break;
3116 case greenland::IntrinsicHelper::HLArrayGetChar:
3117 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
3118 break;
3119 case greenland::IntrinsicHelper::HLArrayGetShort:
3120 cvtAget(cUnit, callInst, kSignedHalf, 1);
3121 break;
3122
3123 case greenland::IntrinsicHelper::HLArrayPut:
3124 case greenland::IntrinsicHelper::HLArrayPutFloat:
3125 cvtAputPrimitive(cUnit, callInst, kWord, 2);
3126 break;
3127 case greenland::IntrinsicHelper::HLArrayPutObject:
3128 cvtAputObj(cUnit, callInst);
3129 break;
3130 case greenland::IntrinsicHelper::HLArrayPutWide:
3131 case greenland::IntrinsicHelper::HLArrayPutDouble:
3132 cvtAputPrimitive(cUnit, callInst, kLong, 3);
3133 break;
3134 case greenland::IntrinsicHelper::HLArrayPutBoolean:
3135 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
3136 break;
3137 case greenland::IntrinsicHelper::HLArrayPutByte:
3138 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
3139 break;
3140 case greenland::IntrinsicHelper::HLArrayPutChar:
3141 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
3142 break;
3143 case greenland::IntrinsicHelper::HLArrayPutShort:
3144 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
3145 break;
3146
3147 case greenland::IntrinsicHelper::HLIGet:
3148 case greenland::IntrinsicHelper::HLIGetFloat:
3149 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3150 break;
3151 case greenland::IntrinsicHelper::HLIGetObject:
3152 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3153 break;
3154 case greenland::IntrinsicHelper::HLIGetWide:
3155 case greenland::IntrinsicHelper::HLIGetDouble:
3156 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3157 break;
3158 case greenland::IntrinsicHelper::HLIGetBoolean:
3159 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3160 false /* obj */);
3161 break;
3162 case greenland::IntrinsicHelper::HLIGetByte:
3163 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3164 false /* obj */);
3165 break;
3166 case greenland::IntrinsicHelper::HLIGetChar:
3167 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3168 false /* obj */);
3169 break;
3170 case greenland::IntrinsicHelper::HLIGetShort:
3171 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3172 false /* obj */);
3173 break;
3174
3175 case greenland::IntrinsicHelper::HLIPut:
3176 case greenland::IntrinsicHelper::HLIPutFloat:
3177 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3178 break;
3179 case greenland::IntrinsicHelper::HLIPutObject:
3180 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3181 break;
3182 case greenland::IntrinsicHelper::HLIPutWide:
3183 case greenland::IntrinsicHelper::HLIPutDouble:
3184 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3185 break;
3186 case greenland::IntrinsicHelper::HLIPutBoolean:
3187 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3188 false /* obj */);
3189 break;
3190 case greenland::IntrinsicHelper::HLIPutByte:
3191 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3192 false /* obj */);
3193 break;
3194 case greenland::IntrinsicHelper::HLIPutChar:
3195 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3196 false /* obj */);
3197 break;
3198 case greenland::IntrinsicHelper::HLIPutShort:
3199 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3200 false /* obj */);
3201 break;
3202
3203 case greenland::IntrinsicHelper::IntToChar:
3204 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3205 break;
3206 case greenland::IntrinsicHelper::IntToShort:
3207 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3208 break;
3209 case greenland::IntrinsicHelper::IntToByte:
3210 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3211 break;
3212
TDYa1274ec8ccd2012-08-11 07:04:57 -07003213 case greenland::IntrinsicHelper::F2I:
3214 case greenland::IntrinsicHelper::D2I:
3215 case greenland::IntrinsicHelper::F2L:
3216 case greenland::IntrinsicHelper::D2L:
3217 cvtFPToInt(cUnit, callInst);
3218 break;
3219
buzbee0967a252012-09-14 10:43:54 -07003220 case greenland::IntrinsicHelper::CmplFloat:
3221 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3222 break;
3223 case greenland::IntrinsicHelper::CmpgFloat:
3224 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3225 break;
3226 case greenland::IntrinsicHelper::CmplDouble:
3227 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3228 break;
3229 case greenland::IntrinsicHelper::CmpgDouble:
3230 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3231 break;
3232
3233 case greenland::IntrinsicHelper::CmpLong:
3234 cvtLongCompare(cUnit, callInst);
3235 break;
3236
3237 case greenland::IntrinsicHelper::SHLLong:
3238 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
3239 break;
3240 case greenland::IntrinsicHelper::SHRLong:
3241 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3242 break;
3243 case greenland::IntrinsicHelper::USHRLong:
3244 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3245 break;
3246 case greenland::IntrinsicHelper::SHLInt:
3247 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3248 break;
3249 case greenland::IntrinsicHelper::SHRInt:
3250 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3251 break;
3252 case greenland::IntrinsicHelper::USHRInt:
3253 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3254 break;
3255
3256 case greenland::IntrinsicHelper::CatchTargets: {
3257 llvm::SwitchInst* swInst =
3258 llvm::dyn_cast<llvm::SwitchInst>(nextIt);
3259 DCHECK(swInst != NULL);
3260 /*
3261 * Discard the edges and the following conditional branch.
3262 * Do a direct branch to the default target (which is the
3263 * "work" portion of the pair.
3264 * TODO: awful code layout - rework
3265 */
3266 llvm::BasicBlock* targetBB = swInst->getDefaultDest();
3267 DCHECK(targetBB != NULL);
3268 opUnconditionalBranch(cUnit,
3269 cUnit->blockToLabelMap.Get(targetBB));
3270 ++it;
3271 // Set next bb to default target - improves code layout
3272 nextBB = targetBB;
3273 }
3274 break;
3275
3276 default:
3277 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3278 << cUnit->intrinsic_helper->GetName(id);
3279 }
3280 }
3281 break;
3282
3283 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3284 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3285 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3286 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3287 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3288 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3289 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3290 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3291 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
3292 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3293 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
3294 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3295 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3296 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3297 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3298 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
3299 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003300 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3301 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3302 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
3303
3304 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3305 break;
3306 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3307 break;
3308
3309 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3310
3311 case llvm::Instruction::Unreachable:
3312 break; // FIXME: can we really ignore these?
3313
3314 case llvm::Instruction::Shl:
3315 case llvm::Instruction::LShr:
3316 case llvm::Instruction::AShr:
3317 case llvm::Instruction::Invoke:
3318 case llvm::Instruction::FPToUI:
TDYa1274ec8ccd2012-08-11 07:04:57 -07003319 case llvm::Instruction::FPToSI:
buzbee0967a252012-09-14 10:43:54 -07003320 case llvm::Instruction::UIToFP:
3321 case llvm::Instruction::PtrToInt:
3322 case llvm::Instruction::IntToPtr:
3323 case llvm::Instruction::FCmp:
3324 case llvm::Instruction::URem:
3325 case llvm::Instruction::UDiv:
3326 case llvm::Instruction::Resume:
3327 case llvm::Instruction::Alloca:
3328 case llvm::Instruction::GetElementPtr:
3329 case llvm::Instruction::Fence:
3330 case llvm::Instruction::AtomicCmpXchg:
3331 case llvm::Instruction::AtomicRMW:
3332 case llvm::Instruction::BitCast:
3333 case llvm::Instruction::VAArg:
3334 case llvm::Instruction::Select:
3335 case llvm::Instruction::UserOp1:
3336 case llvm::Instruction::UserOp2:
3337 case llvm::Instruction::ExtractElement:
3338 case llvm::Instruction::InsertElement:
3339 case llvm::Instruction::ShuffleVector:
3340 case llvm::Instruction::ExtractValue:
3341 case llvm::Instruction::InsertValue:
3342 case llvm::Instruction::LandingPad:
3343 case llvm::Instruction::IndirectBr:
3344 case llvm::Instruction::Load:
3345 case llvm::Instruction::Store:
3346 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3347
3348 default:
3349 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3350 break;
buzbeead8f15e2012-06-18 14:49:45 -07003351 }
3352 }
buzbee2cfc6392012-05-07 14:51:40 -07003353
buzbee0967a252012-09-14 10:43:54 -07003354 if (headLIR != NULL) {
3355 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
buzbee2cfc6392012-05-07 14:51:40 -07003356 }
buzbee0967a252012-09-14 10:43:54 -07003357 if (nextBB != NULL) {
3358 bb = nextBB;
3359 nextBB = NULL;
buzbee6969d502012-06-15 16:40:31 -07003360 }
buzbee6969d502012-06-15 16:40:31 -07003361 }
buzbee2cfc6392012-05-07 14:51:40 -07003362 return false;
3363}
3364
3365/*
3366 * Convert LLVM_IR to MIR:
3367 * o Iterate through the LLVM_IR and construct a graph using
3368 * standard MIR building blocks.
3369 * o Perform a basic-block optimization pass to remove unnecessary
3370 * store/load sequences.
3371 * o Convert the LLVM Value operands into RegLocations where applicable.
3372 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3373 * o Perform register promotion
3374 * o Iterate through the graph a basic block at a time, generating
3375 * LIR.
3376 * o Assemble LIR as usual.
3377 * o Profit.
3378 */
3379void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3380{
buzbeead8f15e2012-06-18 14:49:45 -07003381 llvm::Function* func = cUnit->func;
3382 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003383 // Allocate a list for LIR basic block labels
3384 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07003385 (LIR*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3386 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003387 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003388 for (llvm::Function::iterator i = func->begin(),
3389 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003390 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3391 &labelList[nextLabel++]);
3392 }
buzbeead8f15e2012-06-18 14:49:45 -07003393
3394 /*
3395 * Keep honest - clear regLocations, Value => RegLocation,
3396 * promotion map and VmapTables.
3397 */
3398 cUnit->locMap.clear(); // Start fresh
3399 cUnit->regLocation = NULL;
3400 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3401 i++) {
3402 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3403 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3404 }
3405 cUnit->coreSpillMask = 0;
3406 cUnit->numCoreSpills = 0;
3407 cUnit->fpSpillMask = 0;
3408 cUnit->numFPSpills = 0;
3409 cUnit->coreVmapTable.clear();
3410 cUnit->fpVmapTable.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003411
3412 /*
3413 * At this point, we've lost all knowledge of register promotion.
3414 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003415 * exists - not required for correctness). Normally, this will
3416 * be the first instruction we encounter, so we won't have to iterate
3417 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003418 */
buzbeeca7a5e42012-08-20 11:12:18 -07003419 for (llvm::inst_iterator i = llvm::inst_begin(func),
3420 e = llvm::inst_end(func); i != e; ++i) {
3421 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(&*i);
3422 if (callInst != NULL) {
3423 llvm::Function* callee = callInst->getCalledFunction();
3424 greenland::IntrinsicHelper::IntrinsicId id =
3425 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3426 if (id == greenland::IntrinsicHelper::MethodInfo) {
3427 if (cUnit->printMe) {
3428 LOG(INFO) << "Found MethodInfo";
3429 }
3430 llvm::MDNode* regInfoNode = callInst->getMetadata("RegInfo");
3431 if (regInfoNode != NULL) {
3432 llvm::ConstantInt* numInsValue =
3433 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(0));
3434 llvm::ConstantInt* numRegsValue =
3435 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(1));
3436 llvm::ConstantInt* numOutsValue =
3437 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(2));
3438 llvm::ConstantInt* numCompilerTempsValue =
3439 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(3));
3440 llvm::ConstantInt* numSSARegsValue =
3441 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(4));
3442 if (cUnit->printMe) {
3443 LOG(INFO) << "RegInfo - Ins:" << numInsValue->getZExtValue()
3444 << ", Regs:" << numRegsValue->getZExtValue()
3445 << ", Outs:" << numOutsValue->getZExtValue()
3446 << ", CTemps:" << numCompilerTempsValue->getZExtValue()
3447 << ", SSARegs:" << numSSARegsValue->getZExtValue();
3448 }
3449 }
3450 llvm::MDNode* pmapInfoNode = callInst->getMetadata("PromotionMap");
3451 if (pmapInfoNode != NULL) {
3452 int elems = pmapInfoNode->getNumOperands();
3453 if (cUnit->printMe) {
3454 LOG(INFO) << "PMap size: " << elems;
3455 }
3456 for (int i = 0; i < elems; i++) {
3457 llvm::ConstantInt* rawMapData =
3458 static_cast<llvm::ConstantInt*>(pmapInfoNode->getOperand(i));
3459 uint32_t mapData = rawMapData->getZExtValue();
3460 PromotionMap* p = &cUnit->promotionMap[i];
3461 p->firstInPair = (mapData >> 24) & 0xff;
3462 p->fpReg = (mapData >> 16) & 0xff;
3463 p->coreReg = (mapData >> 8) & 0xff;
3464 p->fpLocation = static_cast<RegLocationType>((mapData >> 4) & 0xf);
3465 if (p->fpLocation == kLocPhysReg) {
3466 oatRecordFpPromotion(cUnit, p->fpReg, i);
3467 }
3468 p->coreLocation = static_cast<RegLocationType>(mapData & 0xf);
3469 if (p->coreLocation == kLocPhysReg) {
3470 oatRecordCorePromotion(cUnit, p->coreReg, i);
3471 }
3472 }
3473 if (cUnit->printMe) {
3474 oatDumpPromotionMap(cUnit);
3475 }
3476 }
3477 break;
3478 }
3479 }
3480 }
3481 oatAdjustSpillMask(cUnit);
3482 cUnit->frameSize = oatComputeFrameSize(cUnit);
buzbeead8f15e2012-06-18 14:49:45 -07003483
3484 // Create RegLocations for arguments
3485 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3486 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3487 for (; it != it_end; ++it) {
3488 llvm::Value* val = it;
3489 createLocFromValue(cUnit, val);
3490 }
3491 // Create RegLocations for all non-argument defintions
3492 for (llvm::inst_iterator i = llvm::inst_begin(func),
3493 e = llvm::inst_end(func); i != e; ++i) {
3494 llvm::Value* val = &*i;
3495 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3496 createLocFromValue(cUnit, val);
3497 }
3498 }
3499
buzbee2cfc6392012-05-07 14:51:40 -07003500 // Walk the blocks, generating code.
3501 for (llvm::Function::iterator i = cUnit->func->begin(),
3502 e = cUnit->func->end(); i != e; ++i) {
3503 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3504 }
3505
3506 handleSuspendLaunchpads(cUnit);
3507
3508 handleThrowLaunchpads(cUnit);
3509
3510 handleIntrinsicLaunchpads(cUnit);
3511
buzbee692be802012-08-29 15:52:59 -07003512 cUnit->func->eraseFromParent();
3513 cUnit->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003514}
3515
3516
3517} // namespace art
3518
3519#endif // ART_USE_QUICK_COMPILER