blob: 83ebf9bfce692837b3c6d371e3d8dc0ccde6abf3 [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
Elliott Hughes74847412012-06-20 18:10:21 -070032static const char* kLabelFormat = "L0x%x_%d";
buzbee2cfc6392012-05-07 14:51:40 -070033
34namespace art {
35extern const RegLocation badLoc;
buzbeeb03f4872012-06-11 15:22:11 -070036RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070037
38llvm::BasicBlock* getLLVMBlock(CompilationUnit* cUnit, int id)
39{
40 return cUnit->idToBlockMap.Get(id);
41}
42
43llvm::Value* getLLVMValue(CompilationUnit* cUnit, int sReg)
44{
45 return (llvm::Value*)oatGrowableListGetElement(&cUnit->llvmValues, sReg);
46}
47
48// Replace the placeholder value with the real definition
49void defineValue(CompilationUnit* cUnit, llvm::Value* val, int sReg)
50{
51 llvm::Value* placeholder = getLLVMValue(cUnit, sReg);
52 CHECK(placeholder != NULL) << "Null placeholder - shouldn't happen";
53 placeholder->replaceAllUsesWith(val);
54 val->takeName(placeholder);
55 cUnit->llvmValues.elemList[sReg] = (intptr_t)val;
buzbee4be777b2012-07-12 14:38:18 -070056 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
57 DCHECK(inst != NULL);
58 inst->eraseFromParent();
buzbee2cfc6392012-05-07 14:51:40 -070059}
60
61llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
62{
63 llvm::Type* res = NULL;
64 if (loc.wide) {
65 if (loc.fp)
buzbee4f1181f2012-06-22 13:52:12 -070066 res = cUnit->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070067 else
buzbee4f1181f2012-06-22 13:52:12 -070068 res = cUnit->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070069 } else {
70 if (loc.fp) {
buzbee4f1181f2012-06-22 13:52:12 -070071 res = cUnit->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070072 } else {
73 if (loc.ref)
74 res = cUnit->irb->GetJObjectTy();
75 else
buzbee4f1181f2012-06-22 13:52:12 -070076 res = cUnit->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -070077 }
78 }
79 return res;
80}
81
buzbeead8f15e2012-06-18 14:49:45 -070082/* Create an in-memory RegLocation from an llvm Value. */
83void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
84{
85 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
86 std::string s(val->getName().str());
87 const char* valName = s.c_str();
buzbeead8f15e2012-06-18 14:49:45 -070088 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
89 DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
90 int baseSReg = INVALID_SREG;
91 int subscript = -1;
92 sscanf(valName, "v%d_%d", &baseSReg, &subscript);
93 if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
94 baseSReg = SSA_METHOD_BASEREG;
95 subscript = 0;
96 }
buzbeead8f15e2012-06-18 14:49:45 -070097 DCHECK_NE(baseSReg, INVALID_SREG);
98 DCHECK_NE(subscript, -1);
99 // TODO: redo during C++'ification
100 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
101 INVALID_REG, INVALID_SREG, INVALID_SREG};
102 llvm::Type* ty = val->getType();
103 loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
104 (ty == cUnit->irb->getDoubleTy()));
105 loc.defined = true;
106 if ((ty == cUnit->irb->getFloatTy()) ||
107 (ty == cUnit->irb->getDoubleTy())) {
108 loc.fp = true;
109 } else if (ty == cUnit->irb->GetJObjectTy()) {
110 loc.ref = true;
111 } else {
112 loc.core = true;
113 }
114 loc.home = false; // Will change during promotion
115 loc.sRegLow = baseSReg;
116 loc.origSReg = cUnit->locMap.size();
117 cUnit->locMap.Put(val, loc);
118}
119
buzbee2cfc6392012-05-07 14:51:40 -0700120void initIR(CompilationUnit* cUnit)
121{
122 cUnit->context = new llvm::LLVMContext();
123 cUnit->module = new llvm::Module("art", *cUnit->context);
124 llvm::StructType::create(*cUnit->context, "JavaObject");
125 llvm::StructType::create(*cUnit->context, "Method");
126 llvm::StructType::create(*cUnit->context, "Thread");
127 cUnit->intrinsic_helper =
128 new greenland::IntrinsicHelper(*cUnit->context, *cUnit->module);
129 cUnit->irb =
130 new greenland::IRBuilder(*cUnit->context, *cUnit->module,
131 *cUnit->intrinsic_helper);
132}
133
134void freeIR(CompilationUnit* cUnit)
135{
136 delete cUnit->irb;
137 delete cUnit->intrinsic_helper;
138 delete cUnit->module;
139 delete cUnit->context;
140}
141
142const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
143 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
144}
145
buzbeef58c12c2012-07-03 15:06:29 -0700146llvm::BasicBlock* findCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
147{
148 BasicBlock* bb = oatFindBlock(cUnit, vaddr);
149 DCHECK(bb != NULL);
150 return getLLVMBlock(cUnit, bb->id);
151}
152
153void convertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
154 int32_t tableOffset, RegLocation rlSrc)
155{
156 const Instruction::PackedSwitchPayload* payload =
157 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
158 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
159
160 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
161
162 llvm::SwitchInst* sw =
163 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
164 payload->case_count);
165
166 for (uint16_t i = 0; i < payload->case_count; ++i) {
167 llvm::BasicBlock* llvmBB =
168 findCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
169 sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
170 }
171 llvm::MDNode* switchNode =
172 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
173 sw->setMetadata("SwitchTable", switchNode);
174 bb->taken = NULL;
175 bb->fallThrough = NULL;
176}
177
buzbeea1da8a52012-07-09 14:00:21 -0700178void convertSparseSwitch(CompilationUnit* cUnit, BasicBlock* bb,
179 int32_t tableOffset, RegLocation rlSrc)
180{
181 const Instruction::SparseSwitchPayload* payload =
182 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
183 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
184
185 const int32_t* keys = payload->GetKeys();
186 const int32_t* targets = payload->GetTargets();
187
188 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
189
190 llvm::SwitchInst* sw =
191 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
192 payload->case_count);
193
194 for (size_t i = 0; i < payload->case_count; ++i) {
195 llvm::BasicBlock* llvmBB =
196 findCaseTarget(cUnit, cUnit->currentDalvikOffset + targets[i]);
197 sw->addCase(cUnit->irb->getInt32(keys[i]), llvmBB);
198 }
199 llvm::MDNode* switchNode =
200 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
201 sw->setMetadata("SwitchTable", switchNode);
202 bb->taken = NULL;
203 bb->fallThrough = NULL;
204}
205
buzbee8fa0fda2012-06-27 15:44:52 -0700206void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
207 greenland::IntrinsicHelper::IntrinsicId id,
208 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700209{
buzbee8fa0fda2012-06-27 15:44:52 -0700210 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700211 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700212 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
213 defineValue(cUnit, res, rlDest.origSReg);
214}
215
216void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
217 greenland::IntrinsicHelper::IntrinsicId id,
218 RegLocation rlSrc)
219{
220 llvm::SmallVector<llvm::Value*, 2> args;
221 args.push_back(cUnit->irb->getInt32(fieldIndex));
222 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
223 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
224 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700225}
226
buzbee101305f2012-06-28 18:00:56 -0700227void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
228 RegLocation rlArray)
229{
230 greenland::IntrinsicHelper::IntrinsicId id;
231 id = greenland::IntrinsicHelper::FillArrayData;
232 llvm::SmallVector<llvm::Value*, 2> args;
233 args.push_back(cUnit->irb->getInt32(offset));
234 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
235 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
236 cUnit->irb->CreateCall(intr, args);
237}
238
buzbee2cfc6392012-05-07 14:51:40 -0700239llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
240 RegLocation loc)
241{
242 greenland::IntrinsicHelper::IntrinsicId id;
243 if (loc.wide) {
244 if (loc.fp) {
245 id = greenland::IntrinsicHelper::ConstDouble;
246 } else {
247 id = greenland::IntrinsicHelper::ConstLong;
248 }
249 } else {
250 if (loc.fp) {
251 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700252 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700253 id = greenland::IntrinsicHelper::ConstObj;
254 } else {
255 id = greenland::IntrinsicHelper::ConstInt;
256 }
257 }
258 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
259 return cUnit->irb->CreateCall(intr, src);
260}
buzbeeb03f4872012-06-11 15:22:11 -0700261
262void emitPopShadowFrame(CompilationUnit* cUnit)
263{
264 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
265 greenland::IntrinsicHelper::PopShadowFrame);
266 cUnit->irb->CreateCall(intr);
267}
268
buzbee2cfc6392012-05-07 14:51:40 -0700269llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
270 RegLocation loc)
271{
272 greenland::IntrinsicHelper::IntrinsicId id;
273 if (loc.wide) {
274 if (loc.fp) {
275 id = greenland::IntrinsicHelper::CopyDouble;
276 } else {
277 id = greenland::IntrinsicHelper::CopyLong;
278 }
279 } else {
280 if (loc.fp) {
281 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700282 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700283 id = greenland::IntrinsicHelper::CopyObj;
284 } else {
285 id = greenland::IntrinsicHelper::CopyInt;
286 }
287 }
288 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
289 return cUnit->irb->CreateCall(intr, src);
290}
291
buzbee32412962012-06-26 16:27:56 -0700292void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
293{
294 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
295 greenland::IntrinsicHelper::GetException);
296 llvm::Value* res = cUnit->irb->CreateCall(func);
297 defineValue(cUnit, res, rlDest.origSReg);
298}
299
300void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
301{
302 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
303 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
304 greenland::IntrinsicHelper::Throw);
305 cUnit->irb->CreateCall(func, src);
306 cUnit->irb->CreateUnreachable();
307}
308
buzbee8fa0fda2012-06-27 15:44:52 -0700309void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
310 greenland::IntrinsicHelper::IntrinsicId id,
311 RegLocation rlSrc)
312{
313 llvm::SmallVector<llvm::Value*, 2> args;
314 args.push_back(cUnit->irb->getInt32(optFlags));
315 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
316 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
317 cUnit->irb->CreateCall(func, args);
318}
319
buzbee76592632012-06-29 15:18:35 -0700320void convertArrayLength(CompilationUnit* cUnit, int optFlags,
321 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700322{
323 llvm::SmallVector<llvm::Value*, 2> args;
324 args.push_back(cUnit->irb->getInt32(optFlags));
325 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
326 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
327 greenland::IntrinsicHelper::ArrayLength);
buzbee76592632012-06-29 15:18:35 -0700328 llvm::Value* res = cUnit->irb->CreateCall(func, args);
329 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700330}
331
buzbee32412962012-06-26 16:27:56 -0700332void convertThrowVerificationError(CompilationUnit* cUnit, int info1, int info2)
333{
334 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
buzbeea1da8a52012-07-09 14:00:21 -0700335 greenland::IntrinsicHelper::ThrowVerificationError);
buzbee32412962012-06-26 16:27:56 -0700336 llvm::SmallVector<llvm::Value*, 2> args;
337 args.push_back(cUnit->irb->getInt32(info1));
338 args.push_back(cUnit->irb->getInt32(info2));
339 cUnit->irb->CreateCall(func, args);
buzbee32412962012-06-26 16:27:56 -0700340}
341
buzbee2cfc6392012-05-07 14:51:40 -0700342void emitSuspendCheck(CompilationUnit* cUnit)
343{
344 greenland::IntrinsicHelper::IntrinsicId id =
345 greenland::IntrinsicHelper::CheckSuspend;
346 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
347 cUnit->irb->CreateCall(intr);
348}
349
350llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
351 llvm::Value* src1, llvm::Value* src2)
352{
353 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700354 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700355 switch(cc) {
356 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
357 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
358 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
359 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
360 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
361 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
362 default: LOG(FATAL) << "Unexpected cc value " << cc;
363 }
364 return res;
365}
366
367void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
368 ConditionCode cc, RegLocation rlSrc1,
369 RegLocation rlSrc2)
370{
371 if (bb->taken->startOffset <= mir->offset) {
372 emitSuspendCheck(cUnit);
373 }
374 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
375 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
376 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
377 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
378 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
379 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700380 // Don't redo the fallthrough branch in the BB driver
381 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700382}
383
384void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
385 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
386{
387 if (bb->taken->startOffset <= mir->offset) {
388 emitSuspendCheck(cUnit);
389 }
390 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
391 llvm::Value* src2;
392 if (rlSrc1.ref) {
393 src2 = cUnit->irb->GetJNull();
394 } else {
395 src2 = cUnit->irb->getInt32(0);
396 }
397 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700398 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
399 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700400 // Don't redo the fallthrough branch in the BB driver
401 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700402}
403
404llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
405 llvm::Value* src1, llvm::Value* src2)
406{
407 greenland::IntrinsicHelper::IntrinsicId id;
408 if (isLong) {
409 if (isDiv) {
410 id = greenland::IntrinsicHelper::DivLong;
411 } else {
412 id = greenland::IntrinsicHelper::RemLong;
413 }
414 } else if (isDiv) {
415 id = greenland::IntrinsicHelper::DivInt;
416 } else {
417 id = greenland::IntrinsicHelper::RemInt;
418 }
419 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
420 llvm::SmallVector<llvm::Value*, 2>args;
421 args.push_back(src1);
422 args.push_back(src2);
423 return cUnit->irb->CreateCall(intr, args);
424}
425
426llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
427 llvm::Value* src1, llvm::Value* src2)
428{
429 llvm::Value* res = NULL;
430 switch(op) {
431 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
432 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700433 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700434 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
435 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
436 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
437 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
438 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
439 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700440 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
441 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
442 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700443 default:
444 LOG(FATAL) << "Invalid op " << op;
445 }
446 return res;
447}
448
449void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
450 RegLocation rlSrc1, RegLocation rlSrc2)
451{
452 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
453 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
454 llvm::Value* res = NULL;
455 switch(op) {
456 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
457 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
458 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
459 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
460 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
461 default:
462 LOG(FATAL) << "Invalid op " << op;
463 }
464 defineValue(cUnit, res, rlDest.origSReg);
465}
466
buzbee4f1181f2012-06-22 13:52:12 -0700467void convertShift(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
468 RegLocation rlSrc1, RegLocation rlSrc2)
469{
470 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
buzbee101305f2012-06-28 18:00:56 -0700471 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
472 /*
473 * TODO: Figure out how best to handle constraining the shift
474 * amount to 31 for int and 63 for long. We take care of this
475 * inline for int and in the out-of-line handler for longs, so
476 * it's a bit of a waste to generate llvm bitcode for this.
477 * Yet more intrinsics?
478 */
479 UNIMPLEMENTED(WARNING) << "llvm shift mismatch";
buzbee4f1181f2012-06-22 13:52:12 -0700480 if (rlDest.wide) {
buzbee101305f2012-06-28 18:00:56 -0700481 // llvm thinks the shift could should be in 64 bits.
482 src2 = cUnit->irb->CreateZExt(src2, cUnit->irb->getInt64Ty());
buzbee4f1181f2012-06-22 13:52:12 -0700483 }
buzbee101305f2012-06-28 18:00:56 -0700484 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
buzbee4f1181f2012-06-22 13:52:12 -0700485 defineValue(cUnit, res, rlDest.origSReg);
486}
487
buzbee2cfc6392012-05-07 14:51:40 -0700488void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
489 RegLocation rlSrc1, RegLocation rlSrc2)
490{
491 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
492 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700493 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700494 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
495 defineValue(cUnit, res, rlDest.origSReg);
496}
497
buzbeeb03f4872012-06-11 15:22:11 -0700498void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
499{
500 int index = -1;
501 DCHECK(newVal != NULL);
502 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
503 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
504 if (cUnit->shadowMap[i] == vReg) {
505 index = i;
506 break;
507 }
508 }
Elliott Hughes74847412012-06-20 18:10:21 -0700509 DCHECK_NE(index, -1) << "Corrupt shadowMap";
buzbeeb03f4872012-06-11 15:22:11 -0700510 greenland::IntrinsicHelper::IntrinsicId id =
511 greenland::IntrinsicHelper::SetShadowFrameEntry;
512 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
513 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
514 llvm::Value* args[] = { newVal, tableSlot };
515 cUnit->irb->CreateCall(func, args);
516}
517
buzbee2cfc6392012-05-07 14:51:40 -0700518void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
519 RegLocation rlSrc1, int32_t imm)
520{
521 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
522 llvm::Value* src2 = cUnit->irb->getInt32(imm);
523 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
524 defineValue(cUnit, res, rlDest.origSReg);
525}
526
buzbee101305f2012-06-28 18:00:56 -0700527/*
528 * Process arguments for invoke. Note: this code is also used to
529 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
530 * The requirements are similar.
531 */
buzbee6969d502012-06-15 16:40:31 -0700532void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700533 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700534{
535 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
536 llvm::SmallVector<llvm::Value*, 10> args;
537 // Insert the invokeType
538 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
539 // Insert the method_idx
540 args.push_back(cUnit->irb->getInt32(info->index));
541 // Insert the optimization flags
542 args.push_back(cUnit->irb->getInt32(info->optFlags));
543 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700544 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700545 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
546 args.push_back(val);
547 i += info->args[i].wide ? 2 : 1;
548 }
549 /*
550 * Choose the invoke return type based on actual usage. Note: may
551 * be different than shorty. For example, if a function return value
552 * is not used, we'll treat this as a void invoke.
553 */
554 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700555 if (isFilledNewArray) {
556 id = greenland::IntrinsicHelper::FilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700557 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700558 id = greenland::IntrinsicHelper::HLInvokeVoid;
559 } else {
560 if (info->result.wide) {
561 if (info->result.fp) {
562 id = greenland::IntrinsicHelper::HLInvokeDouble;
563 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700564 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700565 }
566 } else if (info->result.ref) {
567 id = greenland::IntrinsicHelper::HLInvokeObj;
568 } else if (info->result.fp) {
569 id = greenland::IntrinsicHelper::HLInvokeFloat;
570 } else {
571 id = greenland::IntrinsicHelper::HLInvokeInt;
572 }
573 }
574 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
575 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
576 if (info->result.location != kLocInvalid) {
577 defineValue(cUnit, res, info->result.origSReg);
578 }
579}
580
buzbee101305f2012-06-28 18:00:56 -0700581void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
582 greenland::IntrinsicHelper::IntrinsicId id,
583 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700584{
buzbee6969d502012-06-15 16:40:31 -0700585 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700586 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700587 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
588 defineValue(cUnit, res, rlDest.origSReg);
589}
590
buzbee101305f2012-06-28 18:00:56 -0700591void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
592 RegLocation rlSrc)
593{
594 greenland::IntrinsicHelper::IntrinsicId id;
595 id = greenland::IntrinsicHelper::CheckCast;
596 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
597 llvm::SmallVector<llvm::Value*, 2> args;
598 args.push_back(cUnit->irb->getInt32(type_idx));
599 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
600 cUnit->irb->CreateCall(intr, args);
601}
602
buzbee8fa0fda2012-06-27 15:44:52 -0700603void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
604 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700605{
606 greenland::IntrinsicHelper::IntrinsicId id;
607 id = greenland::IntrinsicHelper::NewInstance;
608 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
609 llvm::Value* index = cUnit->irb->getInt32(type_idx);
610 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
611 defineValue(cUnit, res, rlDest.origSReg);
612}
613
buzbee8fa0fda2012-06-27 15:44:52 -0700614void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
615 RegLocation rlDest, RegLocation rlSrc)
616{
617 greenland::IntrinsicHelper::IntrinsicId id;
618 id = greenland::IntrinsicHelper::NewArray;
619 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
620 llvm::SmallVector<llvm::Value*, 2> args;
621 args.push_back(cUnit->irb->getInt32(type_idx));
622 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
623 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
624 defineValue(cUnit, res, rlDest.origSReg);
625}
626
627void convertAget(CompilationUnit* cUnit, int optFlags,
628 greenland::IntrinsicHelper::IntrinsicId id,
629 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
630{
631 llvm::SmallVector<llvm::Value*, 3> args;
632 args.push_back(cUnit->irb->getInt32(optFlags));
633 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
634 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
635 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
636 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
637 defineValue(cUnit, res, rlDest.origSReg);
638}
639
640void convertAput(CompilationUnit* cUnit, int optFlags,
641 greenland::IntrinsicHelper::IntrinsicId id,
642 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
643{
644 llvm::SmallVector<llvm::Value*, 4> args;
645 args.push_back(cUnit->irb->getInt32(optFlags));
646 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
647 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
648 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
649 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
650 cUnit->irb->CreateCall(intr, args);
651}
652
buzbee101305f2012-06-28 18:00:56 -0700653void convertIget(CompilationUnit* cUnit, int optFlags,
654 greenland::IntrinsicHelper::IntrinsicId id,
655 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
656{
657 llvm::SmallVector<llvm::Value*, 3> args;
658 args.push_back(cUnit->irb->getInt32(optFlags));
659 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
660 args.push_back(cUnit->irb->getInt32(fieldIndex));
661 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
662 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
663 defineValue(cUnit, res, rlDest.origSReg);
664}
665
666void convertIput(CompilationUnit* cUnit, int optFlags,
667 greenland::IntrinsicHelper::IntrinsicId id,
668 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
669{
670 llvm::SmallVector<llvm::Value*, 4> args;
671 args.push_back(cUnit->irb->getInt32(optFlags));
672 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
673 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
674 args.push_back(cUnit->irb->getInt32(fieldIndex));
675 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
676 cUnit->irb->CreateCall(intr, args);
677}
678
buzbee8fa0fda2012-06-27 15:44:52 -0700679void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
680 RegLocation rlDest, RegLocation rlSrc)
681{
682 greenland::IntrinsicHelper::IntrinsicId id;
683 id = greenland::IntrinsicHelper::InstanceOf;
684 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
685 llvm::SmallVector<llvm::Value*, 2> args;
686 args.push_back(cUnit->irb->getInt32(type_idx));
687 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
688 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
689 defineValue(cUnit, res, rlDest.origSReg);
690}
691
buzbee101305f2012-06-28 18:00:56 -0700692void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
693 RegLocation rlSrc)
694{
695 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
696 cUnit->irb->getInt64Ty());
697 defineValue(cUnit, res, rlDest.origSReg);
698}
699
buzbee76592632012-06-29 15:18:35 -0700700void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
701 RegLocation rlSrc)
702{
703 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
704 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
705 defineValue(cUnit, res, rlDest.origSReg);
706}
707
708void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
709 RegLocation rlSrc)
710{
711 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
712 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
713 defineValue(cUnit, res, rlDest.origSReg);
714}
715
716void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
717 RegLocation rlSrc)
718{
719 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
720 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
721 defineValue(cUnit, res, rlDest.origSReg);
722}
723
724void convertWideComparison(CompilationUnit* cUnit,
725 greenland::IntrinsicHelper::IntrinsicId id,
726 RegLocation rlDest, RegLocation rlSrc1,
727 RegLocation rlSrc2)
728{
729 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
730 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
731 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
732 llvm::SmallVector<llvm::Value*, 2> args;
733 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
734 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
735 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
736 defineValue(cUnit, res, rlDest.origSReg);
737}
738
buzbee101305f2012-06-28 18:00:56 -0700739void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
740 RegLocation rlSrc,
741 greenland::IntrinsicHelper::IntrinsicId id)
742{
743 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700744 llvm::Value* res =
745 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
746 defineValue(cUnit, res, rlDest.origSReg);
747}
748
749void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
750 RegLocation rlSrc)
751{
752 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
753 defineValue(cUnit, res, rlDest.origSReg);
754}
755
756void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
757 RegLocation rlSrc)
758{
759 llvm::Value* res =
760 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
761 defineValue(cUnit, res, rlDest.origSReg);
762}
763
764void convertFPToInt(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
765 RegLocation rlSrc)
766{
767 llvm::Value* res =
768 cUnit->irb->CreateFPToSI(getLLVMValue(cUnit, rlSrc.origSReg), ty);
769 defineValue(cUnit, res, rlDest.origSReg);
770}
771
772
773void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
774 RegLocation rlSrc)
775{
776 llvm::Value* res =
777 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
778 defineValue(cUnit, res, rlDest.origSReg);
779}
780
781void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
782 RegLocation rlSrc)
783{
784 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
785 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700786 defineValue(cUnit, res, rlDest.origSReg);
787}
788
buzbee2cfc6392012-05-07 14:51:40 -0700789/*
790 * Target-independent code generation. Use only high-level
791 * load/store utilities here, or target-dependent genXX() handlers
792 * when necessary.
793 */
794bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
795 llvm::BasicBlock* llvmBB, LIR* labelList)
796{
797 bool res = false; // Assume success
798 RegLocation rlSrc[3];
799 RegLocation rlDest = badLoc;
800 RegLocation rlResult = badLoc;
801 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee32412962012-06-26 16:27:56 -0700802 uint32_t vA = mir->dalvikInsn.vA;
buzbee6969d502012-06-15 16:40:31 -0700803 uint32_t vB = mir->dalvikInsn.vB;
804 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700805 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700806
buzbeeb03f4872012-06-11 15:22:11 -0700807 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700808
809 /* Prep Src and Dest locations */
810 int nextSreg = 0;
811 int nextLoc = 0;
812 int attrs = oatDataFlowAttributes[opcode];
813 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
814 if (attrs & DF_UA) {
815 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700816 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700817 nextSreg+= 2;
818 } else {
819 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
820 nextSreg++;
821 }
822 }
823 if (attrs & DF_UB) {
824 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700825 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700826 nextSreg+= 2;
827 } else {
828 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
829 nextSreg++;
830 }
831 }
832 if (attrs & DF_UC) {
833 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700834 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700835 } else {
836 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
837 }
838 }
839 if (attrs & DF_DA) {
840 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700841 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700842 } else {
buzbee15bf9802012-06-12 17:49:27 -0700843 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700844 if (rlDest.ref) {
845 objectDefinition = true;
846 }
buzbee2cfc6392012-05-07 14:51:40 -0700847 }
848 }
849
850 switch (opcode) {
851 case Instruction::NOP:
852 break;
853
854 case Instruction::MOVE:
855 case Instruction::MOVE_OBJECT:
856 case Instruction::MOVE_16:
857 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700858 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700859 case Instruction::MOVE_FROM16:
860 case Instruction::MOVE_WIDE:
861 case Instruction::MOVE_WIDE_16:
862 case Instruction::MOVE_WIDE_FROM16: {
863 /*
864 * Moves/copies are meaningless in pure SSA register form,
865 * but we need to preserve them for the conversion back into
866 * MIR (at least until we stop using the Dalvik register maps).
867 * Insert a dummy intrinsic copy call, which will be recognized
868 * by the quick path and removed by the portable path.
869 */
870 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
871 llvm::Value* res = emitCopy(cUnit, src, rlDest);
872 defineValue(cUnit, res, rlDest.origSReg);
873 }
874 break;
875
876 case Instruction::CONST:
877 case Instruction::CONST_4:
878 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700879 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700880 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
881 defineValue(cUnit, res, rlDest.origSReg);
882 }
883 break;
884
885 case Instruction::CONST_WIDE_16:
886 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700887 // Sign extend to 64 bits
888 int64_t imm = static_cast<int32_t>(vB);
889 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700890 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
891 defineValue(cUnit, res, rlDest.origSReg);
892 }
893 break;
894
895 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700896 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700897 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
898 defineValue(cUnit, res, rlDest.origSReg);
899 }
900 break;
901
902 case Instruction::CONST_WIDE: {
903 llvm::Constant* immValue =
904 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
905 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
906 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700907 }
908 break;
buzbee2cfc6392012-05-07 14:51:40 -0700909 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700910 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700911 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
912 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
913 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700914 }
915 break;
916
buzbee8fa0fda2012-06-27 15:44:52 -0700917 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700918 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700919 rlSrc[0]);
920 break;
921 case Instruction::SPUT:
922 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700923 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700924 rlSrc[0]);
925 } else {
buzbee76592632012-06-29 15:18:35 -0700926 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700927 }
928 break;
929 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700930 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700931 rlSrc[0]);
932 break;
933 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700934 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700935 break;
936 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700937 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700938 break;
939 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -0700940 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700941 break;
942 case Instruction::SPUT_WIDE:
943 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700944 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -0700945 rlSrc[0]);
946 } else {
buzbee76592632012-06-29 15:18:35 -0700947 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -0700948 rlSrc[0]);
949 }
950 break;
951
952 case Instruction::SGET_OBJECT:
953 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
954 break;
955 case Instruction::SGET:
956 if (rlDest.fp) {
957 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
958 } else {
959 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
960 }
961 break;
962 case Instruction::SGET_BOOLEAN:
963 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
964 break;
965 case Instruction::SGET_BYTE:
966 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
967 break;
968 case Instruction::SGET_CHAR:
969 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
970 break;
971 case Instruction::SGET_SHORT:
972 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
973 break;
974 case Instruction::SGET_WIDE:
975 if (rlDest.fp) {
976 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
977 rlDest);
978 } else {
979 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -0700980 }
981 break;
buzbee2cfc6392012-05-07 14:51:40 -0700982
983 case Instruction::RETURN_WIDE:
984 case Instruction::RETURN:
985 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -0700986 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700987 emitSuspendCheck(cUnit);
988 }
buzbeeb03f4872012-06-11 15:22:11 -0700989 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700990 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
991 bb->hasReturn = true;
992 }
993 break;
994
995 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -0700996 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700997 emitSuspendCheck(cUnit);
998 }
buzbeeb03f4872012-06-11 15:22:11 -0700999 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001000 cUnit->irb->CreateRetVoid();
1001 bb->hasReturn = true;
1002 }
1003 break;
1004
1005 case Instruction::IF_EQ:
1006 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1007 break;
1008 case Instruction::IF_NE:
1009 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1010 break;
1011 case Instruction::IF_LT:
1012 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1013 break;
1014 case Instruction::IF_GE:
1015 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1016 break;
1017 case Instruction::IF_GT:
1018 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1019 break;
1020 case Instruction::IF_LE:
1021 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1022 break;
1023 case Instruction::IF_EQZ:
1024 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1025 break;
1026 case Instruction::IF_NEZ:
1027 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1028 break;
1029 case Instruction::IF_LTZ:
1030 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1031 break;
1032 case Instruction::IF_GEZ:
1033 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1034 break;
1035 case Instruction::IF_GTZ:
1036 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1037 break;
1038 case Instruction::IF_LEZ:
1039 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1040 break;
1041
1042 case Instruction::GOTO:
1043 case Instruction::GOTO_16:
1044 case Instruction::GOTO_32: {
1045 if (bb->taken->startOffset <= bb->startOffset) {
1046 emitSuspendCheck(cUnit);
1047 }
1048 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1049 }
1050 break;
1051
1052 case Instruction::ADD_LONG:
1053 case Instruction::ADD_LONG_2ADDR:
1054 case Instruction::ADD_INT:
1055 case Instruction::ADD_INT_2ADDR:
1056 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1057 break;
1058 case Instruction::SUB_LONG:
1059 case Instruction::SUB_LONG_2ADDR:
1060 case Instruction::SUB_INT:
1061 case Instruction::SUB_INT_2ADDR:
1062 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1063 break;
1064 case Instruction::MUL_LONG:
1065 case Instruction::MUL_LONG_2ADDR:
1066 case Instruction::MUL_INT:
1067 case Instruction::MUL_INT_2ADDR:
1068 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1069 break;
1070 case Instruction::DIV_LONG:
1071 case Instruction::DIV_LONG_2ADDR:
1072 case Instruction::DIV_INT:
1073 case Instruction::DIV_INT_2ADDR:
1074 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1075 break;
1076 case Instruction::REM_LONG:
1077 case Instruction::REM_LONG_2ADDR:
1078 case Instruction::REM_INT:
1079 case Instruction::REM_INT_2ADDR:
1080 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1081 break;
1082 case Instruction::AND_LONG:
1083 case Instruction::AND_LONG_2ADDR:
1084 case Instruction::AND_INT:
1085 case Instruction::AND_INT_2ADDR:
1086 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1087 break;
1088 case Instruction::OR_LONG:
1089 case Instruction::OR_LONG_2ADDR:
1090 case Instruction::OR_INT:
1091 case Instruction::OR_INT_2ADDR:
1092 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1093 break;
1094 case Instruction::XOR_LONG:
1095 case Instruction::XOR_LONG_2ADDR:
1096 case Instruction::XOR_INT:
1097 case Instruction::XOR_INT_2ADDR:
1098 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1099 break;
1100 case Instruction::SHL_LONG:
1101 case Instruction::SHL_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001102 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
1103 break;
buzbee2cfc6392012-05-07 14:51:40 -07001104 case Instruction::SHL_INT:
1105 case Instruction::SHL_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001106 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001107 break;
1108 case Instruction::SHR_LONG:
1109 case Instruction::SHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001110 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
1111 break;
buzbee2cfc6392012-05-07 14:51:40 -07001112 case Instruction::SHR_INT:
1113 case Instruction::SHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001114 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001115 break;
1116 case Instruction::USHR_LONG:
1117 case Instruction::USHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001118 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
1119 break;
buzbee2cfc6392012-05-07 14:51:40 -07001120 case Instruction::USHR_INT:
1121 case Instruction::USHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001122 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001123 break;
1124
1125 case Instruction::ADD_INT_LIT16:
1126 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001127 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001128 break;
1129 case Instruction::RSUB_INT:
1130 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001131 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001132 break;
1133 case Instruction::MUL_INT_LIT16:
1134 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001135 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001136 break;
1137 case Instruction::DIV_INT_LIT16:
1138 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001139 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001140 break;
1141 case Instruction::REM_INT_LIT16:
1142 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001143 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001144 break;
1145 case Instruction::AND_INT_LIT16:
1146 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001147 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001148 break;
1149 case Instruction::OR_INT_LIT16:
1150 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001151 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001152 break;
1153 case Instruction::XOR_INT_LIT16:
1154 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001155 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001156 break;
1157 case Instruction::SHL_INT_LIT8:
buzbee4f1181f2012-06-22 13:52:12 -07001158 convertArithOpLit(cUnit, kOpLsl, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001159 break;
1160 case Instruction::SHR_INT_LIT8:
buzbee101305f2012-06-28 18:00:56 -07001161 convertArithOpLit(cUnit, kOpAsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001162 break;
1163 case Instruction::USHR_INT_LIT8:
buzbee101305f2012-06-28 18:00:56 -07001164 convertArithOpLit(cUnit, kOpLsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001165 break;
1166
1167 case Instruction::ADD_FLOAT:
1168 case Instruction::ADD_FLOAT_2ADDR:
1169 case Instruction::ADD_DOUBLE:
1170 case Instruction::ADD_DOUBLE_2ADDR:
1171 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1172 break;
1173
1174 case Instruction::SUB_FLOAT:
1175 case Instruction::SUB_FLOAT_2ADDR:
1176 case Instruction::SUB_DOUBLE:
1177 case Instruction::SUB_DOUBLE_2ADDR:
1178 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1179 break;
1180
1181 case Instruction::MUL_FLOAT:
1182 case Instruction::MUL_FLOAT_2ADDR:
1183 case Instruction::MUL_DOUBLE:
1184 case Instruction::MUL_DOUBLE_2ADDR:
1185 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1186 break;
1187
1188 case Instruction::DIV_FLOAT:
1189 case Instruction::DIV_FLOAT_2ADDR:
1190 case Instruction::DIV_DOUBLE:
1191 case Instruction::DIV_DOUBLE_2ADDR:
1192 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1193 break;
1194
1195 case Instruction::REM_FLOAT:
1196 case Instruction::REM_FLOAT_2ADDR:
1197 case Instruction::REM_DOUBLE:
1198 case Instruction::REM_DOUBLE_2ADDR:
1199 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1200 break;
1201
buzbee6969d502012-06-15 16:40:31 -07001202 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001203 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1204 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001205 break;
1206 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001207 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1208 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001209 break;
1210
1211 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001212 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1213 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001214 break;
1215 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001216 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1217 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001218 break;
1219
1220 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001221 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1222 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001223 break;
1224 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001225 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1226 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001227 break;
1228
1229 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001230 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1231 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001232 break;
1233 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001234 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1235 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001236 break;
1237
1238 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001239 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1240 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001241 break;
1242 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001243 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1244 false /* NewFilledArray */);
1245 break;
1246 case Instruction::FILLED_NEW_ARRAY:
1247 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1248 true /* NewFilledArray */);
1249 break;
1250 case Instruction::FILLED_NEW_ARRAY_RANGE:
1251 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1252 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001253 break;
1254
1255 case Instruction::CONST_STRING:
1256 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001257 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1258 rlDest);
1259 break;
1260
1261 case Instruction::CONST_CLASS:
1262 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1263 rlDest);
1264 break;
1265
1266 case Instruction::CHECK_CAST:
1267 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001268 break;
1269
buzbee4f1181f2012-06-22 13:52:12 -07001270 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001271 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001272 break;
1273
buzbee32412962012-06-26 16:27:56 -07001274 case Instruction::MOVE_EXCEPTION:
1275 convertMoveException(cUnit, rlDest);
1276 break;
1277
1278 case Instruction::THROW:
1279 convertThrow(cUnit, rlSrc[0]);
1280 break;
1281
1282 case Instruction::THROW_VERIFICATION_ERROR:
1283 convertThrowVerificationError(cUnit, vA, vB);
1284 break;
buzbee6969d502012-06-15 16:40:31 -07001285
buzbee2cfc6392012-05-07 14:51:40 -07001286 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001287 case Instruction::MOVE_RESULT:
1288 case Instruction::MOVE_RESULT_OBJECT:
buzbee8fa0fda2012-06-27 15:44:52 -07001289 CHECK(false) << "Unexpected MOVE_RESULT";
buzbee2cfc6392012-05-07 14:51:40 -07001290 break;
1291
1292 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001293 convertMonitorEnterExit(cUnit, optFlags,
1294 greenland::IntrinsicHelper::MonitorEnter,
1295 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001296 break;
1297
1298 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001299 convertMonitorEnterExit(cUnit, optFlags,
1300 greenland::IntrinsicHelper::MonitorExit,
1301 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001302 break;
1303
1304 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001305 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001306 break;
1307
1308 case Instruction::NEW_ARRAY:
1309 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1310 break;
1311
1312 case Instruction::INSTANCE_OF:
1313 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1314 break;
1315
1316 case Instruction::AGET:
1317 if (rlDest.fp) {
1318 convertAget(cUnit, optFlags,
1319 greenland::IntrinsicHelper::HLArrayGetFloat,
1320 rlDest, rlSrc[0], rlSrc[1]);
1321 } else {
1322 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1323 rlDest, rlSrc[0], rlSrc[1]);
1324 }
1325 break;
1326 case Instruction::AGET_OBJECT:
1327 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1328 rlDest, rlSrc[0], rlSrc[1]);
1329 break;
1330 case Instruction::AGET_BOOLEAN:
1331 convertAget(cUnit, optFlags,
1332 greenland::IntrinsicHelper::HLArrayGetBoolean,
1333 rlDest, rlSrc[0], rlSrc[1]);
1334 break;
1335 case Instruction::AGET_BYTE:
1336 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1337 rlDest, rlSrc[0], rlSrc[1]);
1338 break;
1339 case Instruction::AGET_CHAR:
1340 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1341 rlDest, rlSrc[0], rlSrc[1]);
1342 break;
1343 case Instruction::AGET_SHORT:
1344 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1345 rlDest, rlSrc[0], rlSrc[1]);
1346 break;
1347 case Instruction::AGET_WIDE:
1348 if (rlDest.fp) {
1349 convertAget(cUnit, optFlags,
1350 greenland::IntrinsicHelper::HLArrayGetDouble,
1351 rlDest, rlSrc[0], rlSrc[1]);
1352 } else {
1353 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1354 rlDest, rlSrc[0], rlSrc[1]);
1355 }
1356 break;
1357
1358 case Instruction::APUT:
1359 if (rlSrc[0].fp) {
1360 convertAput(cUnit, optFlags,
1361 greenland::IntrinsicHelper::HLArrayPutFloat,
1362 rlSrc[0], rlSrc[1], rlSrc[2]);
1363 } else {
1364 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1365 rlSrc[0], rlSrc[1], rlSrc[2]);
1366 }
1367 break;
1368 case Instruction::APUT_OBJECT:
1369 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1370 rlSrc[0], rlSrc[1], rlSrc[2]);
1371 break;
1372 case Instruction::APUT_BOOLEAN:
1373 convertAput(cUnit, optFlags,
1374 greenland::IntrinsicHelper::HLArrayPutBoolean,
1375 rlSrc[0], rlSrc[1], rlSrc[2]);
1376 break;
1377 case Instruction::APUT_BYTE:
1378 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1379 rlSrc[0], rlSrc[1], rlSrc[2]);
1380 break;
1381 case Instruction::APUT_CHAR:
1382 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1383 rlSrc[0], rlSrc[1], rlSrc[2]);
1384 break;
1385 case Instruction::APUT_SHORT:
1386 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1387 rlSrc[0], rlSrc[1], rlSrc[2]);
1388 break;
1389 case Instruction::APUT_WIDE:
1390 if (rlSrc[0].fp) {
1391 convertAput(cUnit, optFlags,
1392 greenland::IntrinsicHelper::HLArrayPutDouble,
1393 rlSrc[0], rlSrc[1], rlSrc[2]);
1394 } else {
1395 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1396 rlSrc[0], rlSrc[1], rlSrc[2]);
1397 }
1398 break;
1399
buzbee101305f2012-06-28 18:00:56 -07001400 case Instruction::IGET:
1401 if (rlDest.fp) {
1402 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001403 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001404 } else {
1405 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001406 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001407 }
buzbee2cfc6392012-05-07 14:51:40 -07001408 break;
buzbee101305f2012-06-28 18:00:56 -07001409 case Instruction::IGET_OBJECT:
1410 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001411 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001412 break;
1413 case Instruction::IGET_BOOLEAN:
1414 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001415 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001416 break;
1417 case Instruction::IGET_BYTE:
1418 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001419 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001420 break;
1421 case Instruction::IGET_CHAR:
1422 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001423 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001424 break;
1425 case Instruction::IGET_SHORT:
1426 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001427 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001428 break;
1429 case Instruction::IGET_WIDE:
1430 if (rlDest.fp) {
1431 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001432 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001433 } else {
1434 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001435 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001436 }
1437 break;
1438 case Instruction::IPUT:
1439 if (rlDest.fp) {
1440 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1441 rlSrc[0], rlSrc[1], vC);
1442 } else {
1443 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1444 rlSrc[0], rlSrc[1], vC);
1445 }
1446 break;
1447 case Instruction::IPUT_OBJECT:
1448 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1449 rlSrc[0], rlSrc[1], vC);
1450 break;
1451 case Instruction::IPUT_BOOLEAN:
1452 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1453 rlSrc[0], rlSrc[1], vC);
1454 break;
1455 case Instruction::IPUT_BYTE:
1456 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1457 rlSrc[0], rlSrc[1], vC);
1458 break;
1459 case Instruction::IPUT_CHAR:
1460 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1461 rlSrc[0], rlSrc[1], vC);
1462 break;
1463 case Instruction::IPUT_SHORT:
1464 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1465 rlSrc[0], rlSrc[1], vC);
1466 break;
1467 case Instruction::IPUT_WIDE:
1468 if (rlDest.fp) {
1469 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1470 rlSrc[0], rlSrc[1], vC);
1471 } else {
1472 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1473 rlSrc[0], rlSrc[1], vC);
1474 }
buzbee2cfc6392012-05-07 14:51:40 -07001475 break;
1476
1477 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001478 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001479 break;
1480
buzbee76592632012-06-29 15:18:35 -07001481 case Instruction::LONG_TO_INT:
1482 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1483 break;
1484
buzbee101305f2012-06-28 18:00:56 -07001485 case Instruction::INT_TO_LONG:
1486 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001487 break;
1488
buzbee101305f2012-06-28 18:00:56 -07001489 case Instruction::INT_TO_CHAR:
1490 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1491 greenland::IntrinsicHelper::IntToChar);
1492 break;
1493 case Instruction::INT_TO_BYTE:
1494 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1495 greenland::IntrinsicHelper::IntToByte);
1496 break;
1497 case Instruction::INT_TO_SHORT:
1498 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1499 greenland::IntrinsicHelper::IntToShort);
1500 break;
1501
buzbee76592632012-06-29 15:18:35 -07001502 case Instruction::INT_TO_FLOAT:
1503 case Instruction::LONG_TO_FLOAT:
1504 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001505 break;
1506
buzbee76592632012-06-29 15:18:35 -07001507 case Instruction::INT_TO_DOUBLE:
1508 case Instruction::LONG_TO_DOUBLE:
1509 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001510 break;
1511
buzbee76592632012-06-29 15:18:35 -07001512 case Instruction::FLOAT_TO_DOUBLE:
1513 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001514 break;
1515
buzbee76592632012-06-29 15:18:35 -07001516 case Instruction::DOUBLE_TO_FLOAT:
1517 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001518 break;
1519
1520 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001521 case Instruction::NEG_INT:
1522 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001523 break;
1524
1525 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001526 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001527 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001528 break;
1529
buzbee76592632012-06-29 15:18:35 -07001530 case Instruction::NOT_LONG:
1531 case Instruction::NOT_INT:
1532 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001533 break;
1534
buzbee2cfc6392012-05-07 14:51:40 -07001535 case Instruction::FLOAT_TO_INT:
buzbee2cfc6392012-05-07 14:51:40 -07001536 case Instruction::DOUBLE_TO_INT:
buzbee76592632012-06-29 15:18:35 -07001537 convertFPToInt(cUnit, cUnit->irb->getInt32Ty(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001538 break;
1539
buzbee76592632012-06-29 15:18:35 -07001540 case Instruction::FLOAT_TO_LONG:
1541 case Instruction::DOUBLE_TO_LONG:
1542 convertFPToInt(cUnit, cUnit->irb->getInt64Ty(), rlDest, rlSrc[0]);
1543 break;
1544
1545 case Instruction::CMPL_FLOAT:
1546 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1547 rlDest, rlSrc[0], rlSrc[1]);
1548 break;
1549 case Instruction::CMPG_FLOAT:
1550 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1551 rlDest, rlSrc[0], rlSrc[1]);
1552 break;
1553 case Instruction::CMPL_DOUBLE:
1554 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1555 rlDest, rlSrc[0], rlSrc[1]);
1556 break;
1557 case Instruction::CMPG_DOUBLE:
1558 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1559 rlDest, rlSrc[0], rlSrc[1]);
1560 break;
1561 case Instruction::CMP_LONG:
1562 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1563 rlDest, rlSrc[0], rlSrc[1]);
1564 break;
1565
buzbee76592632012-06-29 15:18:35 -07001566 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001567 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001568 break;
1569
1570 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001571 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001572 break;
buzbee2cfc6392012-05-07 14:51:40 -07001573
1574 default:
buzbee32412962012-06-26 16:27:56 -07001575 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001576 res = true;
1577 }
buzbeeb03f4872012-06-11 15:22:11 -07001578 if (objectDefinition) {
1579 setShadowFrameEntry(cUnit, (llvm::Value*)
1580 cUnit->llvmValues.elemList[rlDest.origSReg]);
1581 }
buzbee2cfc6392012-05-07 14:51:40 -07001582 return res;
1583}
1584
1585/* Extended MIR instructions like PHI */
1586void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1587 llvm::BasicBlock* llvmBB)
1588{
1589
1590 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1591 case kMirOpPhi: {
1592 int* incoming = (int*)mir->dalvikInsn.vB;
1593 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
1594 llvm::Type* phiType =
1595 llvmTypeFromLocRec(cUnit, rlDest);
1596 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1597 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1598 RegLocation loc;
1599 if (rlDest.wide) {
buzbee15bf9802012-06-12 17:49:27 -07001600 loc = oatGetSrcWide(cUnit, mir, i);
buzbee2cfc6392012-05-07 14:51:40 -07001601 i++;
1602 } else {
1603 loc = oatGetSrc(cUnit, mir, i);
1604 }
1605 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
1606 getLLVMBlock(cUnit, incoming[i]));
1607 }
1608 defineValue(cUnit, phi, rlDest.origSReg);
1609 break;
1610 }
1611 case kMirOpCopy: {
1612 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1613 break;
1614 }
1615#if defined(TARGET_ARM)
1616 case kMirOpFusedCmplFloat:
1617 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1618 break;
1619 case kMirOpFusedCmpgFloat:
1620 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1621 break;
1622 case kMirOpFusedCmplDouble:
1623 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1624 break;
1625 case kMirOpFusedCmpgDouble:
1626 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1627 break;
1628 case kMirOpFusedCmpLong:
1629 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1630 break;
1631#endif
1632 default:
1633 break;
1634 }
1635}
1636
1637void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1638{
1639 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001640 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001641 arrayRef.push_back(cUnit->irb->getInt32(offset));
1642 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1643 cUnit->irb->SetDexOffset(node);
1644}
1645
1646// Attach method info as metadata to special intrinsic
1647void setMethodInfo(CompilationUnit* cUnit)
1648{
1649 // We don't want dex offset on this
1650 cUnit->irb->SetDexOffset(NULL);
1651 greenland::IntrinsicHelper::IntrinsicId id;
1652 id = greenland::IntrinsicHelper::MethodInfo;
1653 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1654 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1655 llvm::SmallVector<llvm::Value*, 2> regInfo;
1656 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1657 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1658 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1659 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1660 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1661 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1662 inst->setMetadata("RegInfo", regInfoNode);
1663 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1664 llvm::SmallVector<llvm::Value*, 50> pmap;
1665 for (int i = 0; i < promoSize; i++) {
1666 PromotionMap* p = &cUnit->promotionMap[i];
1667 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1668 ((p->fpReg & 0xff) << 16) |
1669 ((p->coreReg & 0xff) << 8) |
1670 ((p->fpLocation & 0xf) << 4) |
1671 (p->coreLocation & 0xf);
1672 pmap.push_back(cUnit->irb->getInt32(mapData));
1673 }
1674 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1675 inst->setMetadata("PromotionMap", mapNode);
1676 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1677}
1678
1679/* Handle the content in each basic block */
1680bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1681{
1682 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1683 cUnit->irb->SetInsertPoint(llvmBB);
1684 setDexOffset(cUnit, bb->startOffset);
1685
1686 if (bb->blockType == kEntryBlock) {
1687 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001688 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1689 cUnit->numDalvikRegisters, true,
1690 kAllocMisc);
1691 for (int i = 0; i < cUnit->numSSARegs; i++) {
1692 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1693 }
1694 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1695 if (canBeRef[i]) {
1696 cUnit->numShadowFrameEntries++;
1697 }
1698 }
1699 if (cUnit->numShadowFrameEntries > 0) {
1700 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1701 cUnit->numShadowFrameEntries, true,
1702 kAllocMisc);
1703 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1704 if (canBeRef[i]) {
1705 cUnit->shadowMap[j++] = i;
1706 }
1707 }
1708 greenland::IntrinsicHelper::IntrinsicId id =
1709 greenland::IntrinsicHelper::AllocaShadowFrame;
1710 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1711 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1712 cUnit->irb->CreateCall(func, entries);
1713 }
buzbee2cfc6392012-05-07 14:51:40 -07001714 } else if (bb->blockType == kExitBlock) {
1715 /*
1716 * Because of the differences between how MIR/LIR and llvm handle exit
1717 * blocks, we won't explicitly covert them. On the llvm-to-lir
1718 * path, it will need to be regenereated.
1719 */
1720 return false;
buzbee6969d502012-06-15 16:40:31 -07001721 } else if (bb->blockType == kExceptionHandling) {
1722 /*
1723 * Because we're deferring null checking, delete the associated empty
1724 * exception block.
1725 * TODO: add new block type for exception blocks that we generate
1726 * greenland code for.
1727 */
1728 llvmBB->eraseFromParent();
1729 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001730 }
1731
1732 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1733
1734 setDexOffset(cUnit, mir->offset);
1735
1736 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
1737 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
1738
1739 /* If we're compiling for the debugger, generate an update callout */
1740 if (cUnit->genDebugger) {
1741 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1742 //genDebuggerUpdate(cUnit, mir->offset);
1743 }
1744
1745 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
1746 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1747 continue;
1748 }
1749
1750 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1751 NULL /* labelList */);
1752 if (notHandled) {
1753 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
1754 mir->offset, dalvikOpcode,
1755 Instruction::Name(dalvikOpcode),
1756 dalvikFormat);
1757 }
1758 }
1759
buzbee4be777b2012-07-12 14:38:18 -07001760 if (bb->blockType == kEntryBlock) {
1761 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1762 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001763 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1764 }
1765
1766 return false;
1767}
1768
buzbee4f4dfc72012-07-02 14:54:44 -07001769char remapShorty(char shortyType) {
1770 /*
1771 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1772 * and longs/doubles are represented as a pair of registers. When sub-word
1773 * arguments (and method results) are passed, they are extended to Dalvik
1774 * virtual register containers. Because llvm is picky about type consistency,
1775 * we must either cast the "real" type to 32-bit container multiple Dalvik
1776 * register types, or always use the expanded values.
1777 * Here, we're doing the latter. We map the shorty signature to container
1778 * types (which is valid so long as we always do a real expansion of passed
1779 * arguments and field loads).
1780 */
1781 switch(shortyType) {
1782 case 'Z' : shortyType = 'I'; break;
1783 case 'B' : shortyType = 'I'; break;
1784 case 'S' : shortyType = 'I'; break;
1785 case 'C' : shortyType = 'I'; break;
1786 default: break;
1787 }
1788 return shortyType;
1789}
1790
buzbee2cfc6392012-05-07 14:51:40 -07001791llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1792
1793 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001794 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001795 greenland::kAccurate);
1796
1797 // Get argument type
1798 std::vector<llvm::Type*> args_type;
1799
1800 // method object
1801 args_type.push_back(cUnit->irb->GetJMethodTy());
1802
1803 // Do we have a "this"?
1804 if ((cUnit->access_flags & kAccStatic) == 0) {
1805 args_type.push_back(cUnit->irb->GetJObjectTy());
1806 }
1807
1808 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001809 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001810 greenland::kAccurate));
1811 }
1812
1813 return llvm::FunctionType::get(ret_type, args_type, false);
1814}
1815
1816bool createFunction(CompilationUnit* cUnit) {
1817 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1818 /* with_signature */ false));
1819 llvm::FunctionType* func_type = getFunctionType(cUnit);
1820
1821 if (func_type == NULL) {
1822 return false;
1823 }
1824
1825 cUnit->func = llvm::Function::Create(func_type,
1826 llvm::Function::ExternalLinkage,
1827 func_name, cUnit->module);
1828
1829 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1830 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1831
1832 arg_iter->setName("method");
1833 ++arg_iter;
1834
1835 int startSReg = cUnit->numRegs;
1836
1837 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1838 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1839 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1840 }
1841
1842 return true;
1843}
1844
1845bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1846{
1847 // Skip the exit block
1848 if (bb->blockType == kExitBlock) {
1849 cUnit->idToBlockMap.Put(bb->id, NULL);
1850 } else {
1851 int offset = bb->startOffset;
1852 bool entryBlock = (bb->blockType == kEntryBlock);
1853 llvm::BasicBlock* llvmBB =
1854 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
Elliott Hughes74847412012-06-20 18:10:21 -07001855 StringPrintf(kLabelFormat, offset, bb->id),
buzbee2cfc6392012-05-07 14:51:40 -07001856 cUnit->func);
1857 if (entryBlock) {
1858 cUnit->entryBB = llvmBB;
1859 cUnit->placeholderBB =
1860 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1861 cUnit->func);
1862 }
1863 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1864 }
1865 return false;
1866}
1867
1868
1869/*
1870 * Convert MIR to LLVM_IR
1871 * o For each ssa name, create LLVM named value. Type these
1872 * appropriately, and ignore high half of wide and double operands.
1873 * o For each MIR basic block, create an LLVM basic block.
1874 * o Iterate through the MIR a basic block at a time, setting arguments
1875 * to recovered ssa name.
1876 */
1877void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
1878{
1879 initIR(cUnit);
1880 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
1881
1882 // Create the function
1883 createFunction(cUnit);
1884
1885 // Create an LLVM basic block for each MIR block in dfs preorder
1886 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
1887 kPreOrderDFSTraversal, false /* isIterative */);
1888 /*
1889 * Create an llvm named value for each MIR SSA name. Note: we'll use
1890 * placeholders for all non-argument values (because we haven't seen
1891 * the definition yet).
1892 */
1893 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
1894 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1895 arg_iter++; /* Skip path method */
1896 for (int i = 0; i < cUnit->numSSARegs; i++) {
1897 llvm::Value* val;
buzbee4be777b2012-07-12 14:38:18 -07001898 if ((i < cUnit->numRegs) || (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee2cfc6392012-05-07 14:51:40 -07001899 // Handle SSA defs, skipping Method* and compiler temps
1900 if (SRegToVReg(cUnit, i) < 0) {
1901 val = NULL;
1902 } else {
buzbee4be777b2012-07-12 14:38:18 -07001903 llvm::Constant* immValue = cUnit->irb->GetJInt(0);
1904 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
buzbee2cfc6392012-05-07 14:51:40 -07001905 val->setName(llvmSSAName(cUnit, i));
1906 }
1907 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
1908 if (cUnit->regLocation[i].wide) {
1909 // Skip high half of wide values
1910 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1911 i++;
1912 }
1913 } else {
1914 // Recover previously-created argument values
1915 llvm::Value* argVal = arg_iter++;
1916 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
buzbee4f4dfc72012-07-02 14:54:44 -07001917 if (cUnit->regLocation[i].wide) {
1918 // Skip high half of wide values.
1919 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1920 i++;
1921 }
buzbee2cfc6392012-05-07 14:51:40 -07001922 }
1923 }
buzbee2cfc6392012-05-07 14:51:40 -07001924
1925 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
1926 kPreOrderDFSTraversal, false /* Iterative */);
1927
buzbee4be777b2012-07-12 14:38:18 -07001928 /*
1929 * In a few rare cases of verification failure, the verifier will
1930 * replace one or more Dalvik opcodes with the special
1931 * throw-verification-failure opcode. This can leave the SSA graph
1932 * in an invalid state, as definitions may be lost, while uses retained.
1933 * To work around this problem, we insert placeholder definitions for
1934 * all Dalvik SSA regs in the "placeholder" block. Here, after
1935 * bitcode conversion is complete, we examine those placeholder definitions
1936 * and delete any with no references (which normally is all of them).
1937 *
1938 * If any definitions remain, we link the placeholder block into the
1939 * CFG. Otherwise, it is deleted.
1940 */
1941 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
1942 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
1943 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
1944 DCHECK(inst != NULL);
1945 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
1946 DCHECK(val != NULL);
1947 if (val->getNumUses() == 0) {
1948 inst->eraseFromParent();
1949 }
1950 }
1951 setDexOffset(cUnit, 0);
1952 if (cUnit->placeholderBB->empty()) {
1953 cUnit->placeholderBB->eraseFromParent();
1954 } else {
1955 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
1956 cUnit->irb->CreateBr(cUnit->entryTargetBB);
1957 cUnit->entryTargetBB = cUnit->placeholderBB;
1958 }
1959 cUnit->irb->SetInsertPoint(cUnit->entryBB);
1960 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07001961
1962 llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction);
1963
buzbeead8f15e2012-06-18 14:49:45 -07001964 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
1965 // Write bitcode to file
1966 std::string errmsg;
1967 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
1968 oatReplaceSpecialChars(fname);
1969 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07001970 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07001971
buzbeead8f15e2012-06-18 14:49:45 -07001972 llvm::OwningPtr<llvm::tool_output_file> out_file(
1973 new llvm::tool_output_file(fname.c_str(), errmsg,
1974 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07001975
buzbeead8f15e2012-06-18 14:49:45 -07001976 if (!errmsg.empty()) {
1977 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
1978 }
1979
1980 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
1981 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07001982 }
buzbee2cfc6392012-05-07 14:51:40 -07001983}
1984
1985RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
1986 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07001987 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001988 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
1989 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07001990 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07001991 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07001992 // FIXME: need to be more robust, handle FP and be in a position to
1993 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07001994 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
1995 memset(&res, 0, sizeof(res));
1996 res.location = kLocPhysReg;
1997 res.lowReg = oatAllocTemp(cUnit);
1998 res.home = true;
1999 res.sRegLow = INVALID_SREG;
2000 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002001 llvm::Type* ty = val->getType();
2002 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2003 (ty == cUnit->irb->getDoubleTy()));
2004 if (res.wide) {
2005 res.highReg = oatAllocTemp(cUnit);
2006 }
buzbee4f1181f2012-06-22 13:52:12 -07002007 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002008 } else {
2009 DCHECK_EQ(valName[0], 'v');
2010 int baseSReg = INVALID_SREG;
2011 sscanf(valName.c_str(), "v%d_", &baseSReg);
2012 res = cUnit->regLocation[baseSReg];
2013 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002014 }
2015 } else {
2016 res = it->second;
2017 }
2018 return res;
2019}
2020
2021Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2022{
2023 Instruction::Code res = Instruction::NOP;
2024 if (isWide) {
2025 switch(op) {
2026 case kOpAdd: res = Instruction::ADD_LONG; break;
2027 case kOpSub: res = Instruction::SUB_LONG; break;
2028 case kOpMul: res = Instruction::MUL_LONG; break;
2029 case kOpDiv: res = Instruction::DIV_LONG; break;
2030 case kOpRem: res = Instruction::REM_LONG; break;
2031 case kOpAnd: res = Instruction::AND_LONG; break;
2032 case kOpOr: res = Instruction::OR_LONG; break;
2033 case kOpXor: res = Instruction::XOR_LONG; break;
2034 case kOpLsl: res = Instruction::SHL_LONG; break;
2035 case kOpLsr: res = Instruction::USHR_LONG; break;
2036 case kOpAsr: res = Instruction::SHR_LONG; break;
2037 default: LOG(FATAL) << "Unexpected OpKind " << op;
2038 }
2039 } else if (isConst){
2040 switch(op) {
2041 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2042 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2043 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2044 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2045 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2046 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2047 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2048 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2049 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2050 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2051 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2052 default: LOG(FATAL) << "Unexpected OpKind " << op;
2053 }
2054 } else {
2055 switch(op) {
2056 case kOpAdd: res = Instruction::ADD_INT; break;
2057 case kOpSub: res = Instruction::SUB_INT; break;
2058 case kOpMul: res = Instruction::MUL_INT; break;
2059 case kOpDiv: res = Instruction::DIV_INT; break;
2060 case kOpRem: res = Instruction::REM_INT; break;
2061 case kOpAnd: res = Instruction::AND_INT; break;
2062 case kOpOr: res = Instruction::OR_INT; break;
2063 case kOpXor: res = Instruction::XOR_INT; break;
2064 case kOpLsl: res = Instruction::SHL_INT; break;
2065 case kOpLsr: res = Instruction::USHR_INT; break;
2066 case kOpAsr: res = Instruction::SHR_INT; break;
2067 default: LOG(FATAL) << "Unexpected OpKind " << op;
2068 }
2069 }
2070 return res;
2071}
2072
buzbee4f1181f2012-06-22 13:52:12 -07002073Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2074{
2075 Instruction::Code res = Instruction::NOP;
2076 if (isWide) {
2077 switch(op) {
2078 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2079 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2080 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2081 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2082 case kOpRem: res = Instruction::REM_DOUBLE; break;
2083 default: LOG(FATAL) << "Unexpected OpKind " << op;
2084 }
2085 } else {
2086 switch(op) {
2087 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2088 case kOpSub: res = Instruction::SUB_FLOAT; break;
2089 case kOpMul: res = Instruction::MUL_FLOAT; break;
2090 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2091 case kOpRem: res = Instruction::REM_FLOAT; break;
2092 default: LOG(FATAL) << "Unexpected OpKind " << op;
2093 }
2094 }
2095 return res;
2096}
2097
2098void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2099{
2100 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002101 /*
2102 * Normally, we won't ever generate an FP operation with an immediate
2103 * operand (not supported in Dex instruction set). However, the IR builder
2104 * may insert them - in particular for createNegFP. Recognize this case
2105 * and deal with it.
2106 */
2107 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2108 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2109 DCHECK(op2C == NULL);
2110 if ((op1C != NULL) && (op == kOpSub)) {
2111 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2112 if (rlDest.wide) {
2113 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2114 } else {
2115 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2116 }
buzbee4f1181f2012-06-22 13:52:12 -07002117 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002118 DCHECK(op1C == NULL);
2119 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2120 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2121 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2122 if (rlDest.wide) {
2123 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2124 } else {
2125 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2126 }
buzbee4f1181f2012-06-22 13:52:12 -07002127 }
2128}
2129
buzbee101305f2012-06-28 18:00:56 -07002130void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2131 Instruction::Code opcode)
2132{
2133 RegLocation rlDest = getLoc(cUnit, inst);
2134 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2135 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2136}
2137
buzbee76592632012-06-29 15:18:35 -07002138void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2139{
2140 RegLocation rlDest = getLoc(cUnit, inst);
2141 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2142 Instruction::Code opcode;
2143 if (rlDest.wide) {
2144 if (rlSrc.wide) {
2145 opcode = Instruction::LONG_TO_DOUBLE;
2146 } else {
2147 opcode = Instruction::INT_TO_DOUBLE;
2148 }
2149 } else {
2150 if (rlSrc.wide) {
2151 opcode = Instruction::LONG_TO_FLOAT;
2152 } else {
2153 opcode = Instruction::INT_TO_FLOAT;
2154 }
2155 }
2156 genConversion(cUnit, opcode, rlDest, rlSrc);
2157}
2158
2159void cvtFPToInt(CompilationUnit* cUnit, llvm::Instruction* inst)
2160{
2161 RegLocation rlDest = getLoc(cUnit, inst);
2162 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2163 Instruction::Code opcode;
2164 if (rlDest.wide) {
2165 if (rlSrc.wide) {
2166 opcode = Instruction::DOUBLE_TO_LONG;
2167 } else {
2168 opcode = Instruction::FLOAT_TO_LONG;
2169 }
2170 } else {
2171 if (rlSrc.wide) {
2172 opcode = Instruction::DOUBLE_TO_INT;
2173 } else {
2174 opcode = Instruction::FLOAT_TO_INT;
2175 }
2176 }
2177 genConversion(cUnit, opcode, rlDest, rlSrc);
2178}
2179
2180void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2181{
2182 RegLocation rlDest = getLoc(cUnit, inst);
2183 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2184 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2185}
2186
2187void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2188{
2189 RegLocation rlDest = getLoc(cUnit, inst);
2190 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2191 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2192 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2193 storeValue(cUnit, rlDest, rlSrc);
2194}
2195
2196void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2197{
2198 RegLocation rlDest = getLoc(cUnit, inst);
2199 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2200 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2201}
2202
2203
buzbee101305f2012-06-28 18:00:56 -07002204void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2205{
2206 // TODO: evaluate src/tgt types and add general support for more than int to long
2207 RegLocation rlDest = getLoc(cUnit, inst);
2208 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2209 DCHECK(rlDest.wide);
2210 DCHECK(!rlSrc.wide);
2211 DCHECK(!rlDest.fp);
2212 DCHECK(!rlSrc.fp);
2213 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2214 if (rlSrc.location == kLocPhysReg) {
2215 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2216 } else {
2217 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2218 }
2219 if (isSigned) {
2220 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2221 } else {
2222 loadConstant(cUnit, rlResult.highReg, 0);
2223 }
2224 storeValueWide(cUnit, rlDest, rlResult);
2225}
2226
buzbee2cfc6392012-05-07 14:51:40 -07002227void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2228{
2229 RegLocation rlDest = getLoc(cUnit, inst);
2230 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002231 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002232 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2233 if ((op == kOpSub) && (lhsImm != NULL)) {
2234 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002235 if (rlSrc1.wide) {
2236 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2237 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2238 } else {
2239 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2240 lhsImm->getSExtValue());
2241 }
buzbee4f1181f2012-06-22 13:52:12 -07002242 return;
2243 }
2244 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002245 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2246 llvm::Value* rhs = inst->getOperand(1);
2247 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2248 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
2249 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, src2->getSExtValue());
2250 } else {
2251 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
2252 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2253 if (rlDest.wide) {
2254 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2255 } else {
2256 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2257 }
2258 }
2259}
2260
buzbee101305f2012-06-28 18:00:56 -07002261void cvtShiftOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2262{
2263 if (inst->getType() == cUnit->irb->getInt64Ty()) {
2264 /*
2265 * llvm wants the shift amount to be 64 bits, whereas we've constained
2266 * it to be in 6 bits. It should always be held as an unnamed temp
2267 * at this point that was the result of a previous UExt. We'll backtrack
2268 * to find the pre-extension value and use that.
2269 * TODO: probably better to handle this in cvtIntExt() or just intrinsify
2270 */
2271 RegLocation rlDest = getLoc(cUnit, inst);
2272 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2273 RegLocation rlShift = getLoc(cUnit, inst->getOperand(1));
2274 DCHECK(rlShift.wide);
2275 DCHECK_EQ(rlShift.sRegLow, INVALID_SREG);
2276 // Now, free the temp registers - we won't need them.
2277 // TODO: kill the dead extend ops
2278 oatFreeTemp(cUnit, rlShift.lowReg);
2279 oatFreeTemp(cUnit, rlShift.highReg);
2280 // Get the pre-extend operand
2281 llvm::Instruction* extInst =
2282 llvm::dyn_cast<llvm::Instruction>(inst->getOperand(1));
2283 DCHECK(extInst != NULL);
2284 rlShift = getLoc(cUnit, extInst->getOperand(0));
2285 DCHECK(!rlShift.wide);
2286 Instruction::Code opcode;
2287 if (op == kOpLsl)
2288 opcode = Instruction::SHL_LONG;
2289 else if (op == kOpAsr)
2290 opcode = Instruction::SHR_LONG;
2291 else {
2292 DCHECK_EQ(op, kOpLsr);
2293 opcode = Instruction::USHR_LONG;
2294 }
2295 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2296 } else {
2297 cvtBinOp(cUnit, op, inst);
2298 }
2299}
2300
buzbee2cfc6392012-05-07 14:51:40 -07002301void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2302{
2303 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2304 DCHECK(brInst != NULL);
2305 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2306 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2307 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2308}
2309
2310void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2311{
2312 // Nop - these have already been processed
2313}
2314
2315void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2316{
2317 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2318 llvm::Value* retVal = retInst->getReturnValue();
2319 if (retVal != NULL) {
2320 RegLocation rlSrc = getLoc(cUnit, retVal);
2321 if (rlSrc.wide) {
2322 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2323 } else {
2324 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2325 }
2326 }
2327 genExitSequence(cUnit);
2328}
2329
2330ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2331{
2332 ConditionCode res = kCondAl;
2333 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002334 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002335 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2336 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2337 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002338 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002339 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002340 default: LOG(FATAL) << "Unexpected llvm condition";
2341 }
2342 return res;
2343}
2344
2345void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2346{
2347 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2348 UNIMPLEMENTED(FATAL);
2349}
2350
2351void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2352 llvm::BranchInst* brInst)
2353{
2354 // Get targets
2355 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2356 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2357 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2358 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2359 // Get comparison operands
2360 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2361 ConditionCode cond = getCond(iCmpInst->getPredicate());
2362 llvm::Value* lhs = iCmpInst->getOperand(0);
2363 // Not expecting a constant as 1st operand
2364 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2365 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2366 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2367 llvm::Value* rhs = inst->getOperand(1);
2368#if defined(TARGET_MIPS)
2369 // Compare and branch in one shot
2370 (void)taken;
2371 (void)cond;
2372 (void)rhs;
2373 UNIMPLEMENTED(FATAL);
2374#else
2375 //Compare, then branch
2376 // TODO: handle fused CMP_LONG/IF_xxZ case
2377 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2378 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002379 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2380 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002381 } else {
2382 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2383 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2384 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2385 }
2386 opCondBranch(cUnit, cond, taken);
2387#endif
2388 // Fallthrough
2389 opUnconditionalBranch(cUnit, fallThrough);
2390}
2391
2392void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2393 llvm::Function* callee)
2394{
2395 UNIMPLEMENTED(FATAL);
2396}
2397
buzbee2cfc6392012-05-07 14:51:40 -07002398void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2399{
buzbee4f1181f2012-06-22 13:52:12 -07002400 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002401 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2402 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002403 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2404 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002405 if (rlSrc.wide) {
2406 storeValueWide(cUnit, rlDest, rlSrc);
2407 } else {
2408 storeValue(cUnit, rlDest, rlSrc);
2409 }
2410}
2411
2412// Note: Immediate arg is a ConstantInt regardless of result type
2413void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2414{
buzbee4f1181f2012-06-22 13:52:12 -07002415 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002416 llvm::ConstantInt* src =
2417 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2418 uint64_t immval = src->getZExtValue();
2419 RegLocation rlDest = getLoc(cUnit, callInst);
2420 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2421 if (rlDest.wide) {
2422 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2423 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2424 storeValueWide(cUnit, rlDest, rlResult);
2425 } else {
2426 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2427 storeValue(cUnit, rlDest, rlResult);
2428 }
2429}
2430
buzbee101305f2012-06-28 18:00:56 -07002431void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2432 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002433{
buzbee4f1181f2012-06-22 13:52:12 -07002434 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002435 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002436 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002437 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002438 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002439 if (isString) {
2440 genConstString(cUnit, index, rlDest);
2441 } else {
2442 genConstClass(cUnit, index, rlDest);
2443 }
2444}
2445
2446void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2447{
2448 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2449 llvm::ConstantInt* offsetVal =
2450 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2451 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2452 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002453}
2454
buzbee4f1181f2012-06-22 13:52:12 -07002455void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2456{
buzbee32412962012-06-26 16:27:56 -07002457 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002458 llvm::ConstantInt* typeIdxVal =
2459 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2460 uint32_t typeIdx = typeIdxVal->getZExtValue();
2461 RegLocation rlDest = getLoc(cUnit, callInst);
2462 genNewInstance(cUnit, typeIdx, rlDest);
2463}
2464
buzbee8fa0fda2012-06-27 15:44:52 -07002465void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2466{
2467 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2468 llvm::ConstantInt* typeIdxVal =
2469 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2470 uint32_t typeIdx = typeIdxVal->getZExtValue();
2471 llvm::Value* len = callInst->getArgOperand(1);
2472 RegLocation rlLen = getLoc(cUnit, len);
2473 RegLocation rlDest = getLoc(cUnit, callInst);
2474 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2475}
2476
2477void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2478{
2479 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2480 llvm::ConstantInt* typeIdxVal =
2481 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2482 uint32_t typeIdx = typeIdxVal->getZExtValue();
2483 llvm::Value* src = callInst->getArgOperand(1);
2484 RegLocation rlSrc = getLoc(cUnit, src);
2485 RegLocation rlDest = getLoc(cUnit, callInst);
2486 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2487}
2488
buzbee32412962012-06-26 16:27:56 -07002489void cvtThrowVerificationError(CompilationUnit* cUnit, llvm::CallInst* callInst)
2490{
2491 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2492 llvm::ConstantInt* info1 =
2493 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2494 llvm::ConstantInt* info2 =
2495 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2496 genThrowVerificationError(cUnit, info1->getZExtValue(), info2->getZExtValue());
2497}
2498
2499void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2500{
2501 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2502 llvm::Value* src = callInst->getArgOperand(0);
2503 RegLocation rlSrc = getLoc(cUnit, src);
2504 genThrow(cUnit, rlSrc);
2505}
2506
buzbee8fa0fda2012-06-27 15:44:52 -07002507void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2508 llvm::CallInst* callInst)
2509{
2510 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2511 llvm::ConstantInt* optFlags =
2512 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2513 llvm::Value* src = callInst->getArgOperand(1);
2514 RegLocation rlSrc = getLoc(cUnit, src);
2515 if (isEnter) {
2516 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2517 } else {
2518 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2519 }
2520}
2521
buzbee76592632012-06-29 15:18:35 -07002522void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002523{
2524 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2525 llvm::ConstantInt* optFlags =
2526 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2527 llvm::Value* src = callInst->getArgOperand(1);
2528 RegLocation rlSrc = getLoc(cUnit, src);
2529 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2530 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2531 RegLocation rlDest = getLoc(cUnit, callInst);
2532 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2533 int lenOffset = Array::LengthOffset().Int32Value();
2534 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2535 storeValue(cUnit, rlDest, rlResult);
2536}
2537
buzbee32412962012-06-26 16:27:56 -07002538void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2539{
2540 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
2541 int exOffset = Thread::ExceptionOffset().Int32Value();
2542 RegLocation rlDest = getLoc(cUnit, callInst);
2543 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2544#if defined(TARGET_X86)
2545 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
2546 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
2547#else
2548 int resetReg = oatAllocTemp(cUnit);
2549 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
2550 loadConstant(cUnit, resetReg, 0);
2551 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
2552 oatFreeTemp(cUnit, resetReg);
2553#endif
2554 storeValue(cUnit, rlDest, rlResult);
2555}
2556
buzbee4f1181f2012-06-22 13:52:12 -07002557void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2558 bool isObject)
2559{
buzbee32412962012-06-26 16:27:56 -07002560 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002561 llvm::ConstantInt* typeIdxVal =
2562 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2563 uint32_t typeIdx = typeIdxVal->getZExtValue();
2564 RegLocation rlDest = getLoc(cUnit, callInst);
2565 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2566}
2567
buzbee8fa0fda2012-06-27 15:44:52 -07002568void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2569 bool isObject)
2570{
2571 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2572 llvm::ConstantInt* typeIdxVal =
2573 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2574 uint32_t typeIdx = typeIdxVal->getZExtValue();
2575 llvm::Value* src = callInst->getArgOperand(1);
2576 RegLocation rlSrc = getLoc(cUnit, src);
2577 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2578}
2579
2580void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2581 int scale)
2582{
2583 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2584 llvm::ConstantInt* optFlags =
2585 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2586 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2587 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2588 RegLocation rlDest = getLoc(cUnit, callInst);
2589 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2590 rlDest, scale);
2591}
2592
2593void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002594 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002595{
2596 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2597 llvm::ConstantInt* optFlags =
2598 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2599 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2600 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2601 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002602 if (isObject) {
2603 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2604 rlSrc, scale);
2605 } else {
2606 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2607 rlSrc, scale);
2608 }
2609}
2610
2611void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2612{
2613 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2614}
2615
2616void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2617 OpSize size, int scale)
2618{
2619 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002620}
2621
buzbee101305f2012-06-28 18:00:56 -07002622void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2623 bool isWide, bool isObj)
2624{
2625 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2626 llvm::ConstantInt* optFlags =
2627 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2628 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2629 llvm::ConstantInt* fieldIdx =
2630 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2631 RegLocation rlDest = getLoc(cUnit, callInst);
2632 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2633 size, rlDest, rlObj, isWide, isObj);
2634}
2635
2636void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2637 bool isWide, bool isObj)
2638{
2639 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2640 llvm::ConstantInt* optFlags =
2641 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2642 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2643 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2644 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002645 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002646 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2647 size, rlSrc, rlObj, isWide, isObj);
2648}
2649
2650void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2651{
2652 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2653 llvm::ConstantInt* typeIdx =
2654 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2655 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2656 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2657}
2658
buzbee76592632012-06-29 15:18:35 -07002659void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2660 Instruction::Code opcode)
2661{
2662 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2663 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2664 RegLocation rlDest = getLoc(cUnit, callInst);
2665 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2666}
2667
2668void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2669{
2670 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2671 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2672 RegLocation rlDest = getLoc(cUnit, callInst);
2673 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2674}
2675
buzbeef58c12c2012-07-03 15:06:29 -07002676void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2677{
2678 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2679 DCHECK(swInst != NULL);
2680 llvm::Value* testVal = swInst->getCondition();
2681 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2682 DCHECK(tableOffsetNode != NULL);
2683 llvm::ConstantInt* tableOffsetValue =
2684 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2685 int32_t tableOffset = tableOffsetValue->getSExtValue();
2686 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeea1da8a52012-07-09 14:00:21 -07002687 const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2688 u2 tableMagic = *table;
2689 if (tableMagic == 0x100) {
2690 genPackedSwitch(cUnit, tableOffset, rlSrc);
2691 } else {
2692 DCHECK_EQ(tableMagic, 0x200);
2693 genSparseSwitch(cUnit, tableOffset, rlSrc);
2694 }
buzbeef58c12c2012-07-03 15:06:29 -07002695}
2696
buzbee6969d502012-06-15 16:40:31 -07002697void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002698 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002699{
2700 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2701 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002702 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002703 info->result.location = kLocInvalid;
2704 } else {
2705 info->result = getLoc(cUnit, callInst);
2706 }
2707 llvm::ConstantInt* invokeTypeVal =
2708 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2709 llvm::ConstantInt* methodIndexVal =
2710 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2711 llvm::ConstantInt* optFlagsVal =
2712 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2713 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2714 info->index = methodIndexVal->getZExtValue();
2715 info->optFlags = optFlagsVal->getZExtValue();
2716 info->offset = cUnit->currentDalvikOffset;
2717
buzbee6969d502012-06-15 16:40:31 -07002718 // Count the argument words, and then build argument array.
2719 info->numArgWords = 0;
2720 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2721 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2722 info->numArgWords += tLoc.wide ? 2 : 1;
2723 }
2724 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2725 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2726 // Now, fill in the location records, synthesizing high loc of wide vals
2727 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002728 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002729 if (info->args[next].wide) {
2730 next++;
2731 // TODO: Might make sense to mark this as an invalid loc
2732 info->args[next].origSReg = info->args[next-1].origSReg+1;
2733 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2734 }
2735 next++;
2736 }
buzbee4f4dfc72012-07-02 14:54:44 -07002737 // TODO - rework such that we no longer need isRange
2738 info->isRange = (info->numArgWords > 5);
2739
buzbee76592632012-06-29 15:18:35 -07002740 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002741 genFilledNewArray(cUnit, info);
2742 } else {
2743 genInvoke(cUnit, info);
2744 }
buzbee6969d502012-06-15 16:40:31 -07002745}
2746
buzbeead8f15e2012-06-18 14:49:45 -07002747/* Look up the RegLocation associated with a Value. Must already be defined */
2748RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2749{
2750 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2751 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2752 return it->second;
2753}
2754
buzbee2cfc6392012-05-07 14:51:40 -07002755bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2756{
2757 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2758 // Define the starting label
2759 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2760 // Extract the starting offset from the block's name
2761 if (!isEntry) {
2762 const char* blockName = bb->getName().str().c_str();
2763 int dummy;
Elliott Hughes74847412012-06-20 18:10:21 -07002764 sscanf(blockName, kLabelFormat, &blockLabel->operands[0], &dummy);
buzbee2cfc6392012-05-07 14:51:40 -07002765 }
2766 // Set the label kind
2767 blockLabel->opcode = kPseudoNormalBlockLabel;
2768 // Insert the label
2769 oatAppendLIR(cUnit, blockLabel);
2770
2771 // Free temp registers and reset redundant store tracking */
2772 oatResetRegPool(cUnit);
2773 oatResetDefTracking(cUnit);
2774
2775 //TODO: restore oat incoming liveness optimization
2776 oatClobberAllRegs(cUnit);
2777
buzbee6969d502012-06-15 16:40:31 -07002778 LIR* headLIR = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07002779
2780 if (isEntry) {
2781 cUnit->currentDalvikOffset = 0;
buzbeead8f15e2012-06-18 14:49:45 -07002782 RegLocation* argLocs = (RegLocation*)
2783 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2784 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2785 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2786 for (unsigned i = 0; it != it_end; ++it) {
2787 llvm::Value* val = it;
2788 argLocs[i++] = valToLoc(cUnit, val);
2789 llvm::Type* ty = val->getType();
2790 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2791 argLocs[i++].sRegLow = INVALID_SREG;
2792 }
2793 }
2794 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
buzbee2cfc6392012-05-07 14:51:40 -07002795 }
2796
2797 // Visit all of the instructions in the block
2798 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2799 llvm::Instruction* inst = it;
2800 llvm::BasicBlock::iterator nextIt = ++it;
2801 // Extract the Dalvik offset from the instruction
2802 uint32_t opcode = inst->getOpcode();
2803 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2804 if (dexOffsetNode != NULL) {
2805 llvm::ConstantInt* dexOffsetValue =
2806 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2807 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2808 }
2809
buzbee6969d502012-06-15 16:40:31 -07002810 oatResetRegPool(cUnit);
2811 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2812 oatClobberAllRegs(cUnit);
2813 }
2814
2815 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2816 oatResetDefTracking(cUnit);
2817 }
2818
2819#ifndef NDEBUG
2820 /* Reset temp tracking sanity check */
2821 cUnit->liveSReg = INVALID_SREG;
2822#endif
2823
2824 LIR* boundaryLIR;
2825 const char* instStr = "boundary";
2826 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
2827 (intptr_t) instStr);
2828 cUnit->boundaryMap.Overwrite(cUnit->currentDalvikOffset, boundaryLIR);
2829
2830 /* Remember the first LIR for thisl block*/
2831 if (headLIR == NULL) {
2832 headLIR = boundaryLIR;
2833 headLIR->defMask = ENCODE_ALL;
2834 }
2835
buzbee2cfc6392012-05-07 14:51:40 -07002836 switch(opcode) {
2837
2838 case llvm::Instruction::ICmp: {
2839 llvm::Instruction* nextInst = nextIt;
2840 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2841 if (brInst != NULL /* and... */) {
2842 cvtICmpBr(cUnit, inst, brInst);
2843 ++it;
2844 } else {
2845 cvtICmp(cUnit, inst);
2846 }
2847 }
2848 break;
2849
2850 case llvm::Instruction::Call: {
2851 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2852 llvm::Function* callee = callInst->getCalledFunction();
2853 greenland::IntrinsicHelper::IntrinsicId id =
2854 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2855 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07002856 case greenland::IntrinsicHelper::AllocaShadowFrame:
2857 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07002858 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07002859 // Ignore shadow frame stuff for quick compiler
2860 break;
buzbee2cfc6392012-05-07 14:51:40 -07002861 case greenland::IntrinsicHelper::CopyInt:
2862 case greenland::IntrinsicHelper::CopyObj:
2863 case greenland::IntrinsicHelper::CopyFloat:
2864 case greenland::IntrinsicHelper::CopyLong:
2865 case greenland::IntrinsicHelper::CopyDouble:
2866 cvtCopy(cUnit, callInst);
2867 break;
2868 case greenland::IntrinsicHelper::ConstInt:
2869 case greenland::IntrinsicHelper::ConstObj:
2870 case greenland::IntrinsicHelper::ConstLong:
2871 case greenland::IntrinsicHelper::ConstFloat:
2872 case greenland::IntrinsicHelper::ConstDouble:
2873 cvtConst(cUnit, callInst);
2874 break;
buzbee4f1181f2012-06-22 13:52:12 -07002875 case greenland::IntrinsicHelper::DivInt:
2876 case greenland::IntrinsicHelper::DivLong:
2877 cvtBinOp(cUnit, kOpDiv, inst);
2878 break;
2879 case greenland::IntrinsicHelper::RemInt:
2880 case greenland::IntrinsicHelper::RemLong:
2881 cvtBinOp(cUnit, kOpRem, inst);
2882 break;
buzbee2cfc6392012-05-07 14:51:40 -07002883 case greenland::IntrinsicHelper::MethodInfo:
buzbeead8f15e2012-06-18 14:49:45 -07002884 // Already dealt with - just ignore it here.
buzbee2cfc6392012-05-07 14:51:40 -07002885 break;
2886 case greenland::IntrinsicHelper::CheckSuspend:
2887 genSuspendTest(cUnit, 0 /* optFlags already applied */);
2888 break;
buzbee4f1181f2012-06-22 13:52:12 -07002889 case greenland::IntrinsicHelper::HLInvokeObj:
buzbee8fa0fda2012-06-27 15:44:52 -07002890 case greenland::IntrinsicHelper::HLInvokeFloat:
2891 case greenland::IntrinsicHelper::HLInvokeDouble:
2892 case greenland::IntrinsicHelper::HLInvokeLong:
2893 case greenland::IntrinsicHelper::HLInvokeInt:
buzbee101305f2012-06-28 18:00:56 -07002894 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
buzbee4f1181f2012-06-22 13:52:12 -07002895 break;
buzbee6969d502012-06-15 16:40:31 -07002896 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbee101305f2012-06-28 18:00:56 -07002897 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
2898 break;
2899 case greenland::IntrinsicHelper::FilledNewArray:
2900 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
2901 break;
2902 case greenland::IntrinsicHelper::FillArrayData:
2903 cvtFillArrayData(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07002904 break;
2905 case greenland::IntrinsicHelper::ConstString:
buzbee101305f2012-06-28 18:00:56 -07002906 cvtConstObject(cUnit, callInst, true /* isString */);
2907 break;
2908 case greenland::IntrinsicHelper::ConstClass:
2909 cvtConstObject(cUnit, callInst, false /* isString */);
2910 break;
2911 case greenland::IntrinsicHelper::CheckCast:
2912 cvtCheckCast(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07002913 break;
buzbee4f1181f2012-06-22 13:52:12 -07002914 case greenland::IntrinsicHelper::NewInstance:
2915 cvtNewInstance(cUnit, callInst);
2916 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002917 case greenland::IntrinsicHelper::HLSgetObject:
buzbee4f1181f2012-06-22 13:52:12 -07002918 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
2919 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002920 case greenland::IntrinsicHelper::HLSget:
2921 case greenland::IntrinsicHelper::HLSgetFloat:
2922 case greenland::IntrinsicHelper::HLSgetBoolean:
2923 case greenland::IntrinsicHelper::HLSgetByte:
2924 case greenland::IntrinsicHelper::HLSgetChar:
2925 case greenland::IntrinsicHelper::HLSgetShort:
2926 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
2927 break;
2928 case greenland::IntrinsicHelper::HLSgetWide:
2929 case greenland::IntrinsicHelper::HLSgetDouble:
2930 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
2931 break;
buzbee76592632012-06-29 15:18:35 -07002932 case greenland::IntrinsicHelper::HLSput:
2933 case greenland::IntrinsicHelper::HLSputFloat:
2934 case greenland::IntrinsicHelper::HLSputBoolean:
2935 case greenland::IntrinsicHelper::HLSputByte:
2936 case greenland::IntrinsicHelper::HLSputChar:
2937 case greenland::IntrinsicHelper::HLSputShort:
2938 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
2939 break;
2940 case greenland::IntrinsicHelper::HLSputWide:
2941 case greenland::IntrinsicHelper::HLSputDouble:
2942 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
2943 break;
buzbeea1da8a52012-07-09 14:00:21 -07002944 case greenland::IntrinsicHelper::HLSputObject:
2945 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
2946 break;
buzbee32412962012-06-26 16:27:56 -07002947 case greenland::IntrinsicHelper::GetException:
2948 cvtMoveException(cUnit, callInst);
2949 break;
2950 case greenland::IntrinsicHelper::Throw:
2951 cvtThrow(cUnit, callInst);
2952 break;
2953 case greenland::IntrinsicHelper::ThrowVerificationError:
buzbee8fa0fda2012-06-27 15:44:52 -07002954 cvtThrowVerificationError(cUnit, callInst);
buzbee32412962012-06-26 16:27:56 -07002955 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002956 case greenland::IntrinsicHelper::MonitorEnter:
2957 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
2958 break;
2959 case greenland::IntrinsicHelper::MonitorExit:
2960 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
2961 break;
2962 case greenland::IntrinsicHelper::ArrayLength:
buzbee76592632012-06-29 15:18:35 -07002963 cvtArrayLength(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07002964 break;
2965 case greenland::IntrinsicHelper::NewArray:
2966 cvtNewArray(cUnit, callInst);
2967 break;
2968 case greenland::IntrinsicHelper::InstanceOf:
2969 cvtInstanceOf(cUnit, callInst);
2970 break;
2971
2972 case greenland::IntrinsicHelper::HLArrayGet:
2973 case greenland::IntrinsicHelper::HLArrayGetObject:
2974 case greenland::IntrinsicHelper::HLArrayGetFloat:
2975 cvtAget(cUnit, callInst, kWord, 2);
2976 break;
2977 case greenland::IntrinsicHelper::HLArrayGetWide:
2978 case greenland::IntrinsicHelper::HLArrayGetDouble:
2979 cvtAget(cUnit, callInst, kLong, 3);
2980 break;
2981 case greenland::IntrinsicHelper::HLArrayGetBoolean:
2982 cvtAget(cUnit, callInst, kUnsignedByte, 0);
2983 break;
2984 case greenland::IntrinsicHelper::HLArrayGetByte:
2985 cvtAget(cUnit, callInst, kSignedByte, 0);
2986 break;
2987 case greenland::IntrinsicHelper::HLArrayGetChar:
2988 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
2989 break;
2990 case greenland::IntrinsicHelper::HLArrayGetShort:
2991 cvtAget(cUnit, callInst, kSignedHalf, 1);
2992 break;
2993
2994 case greenland::IntrinsicHelper::HLArrayPut:
buzbee8fa0fda2012-06-27 15:44:52 -07002995 case greenland::IntrinsicHelper::HLArrayPutFloat:
buzbeef1f86362012-07-10 15:18:31 -07002996 cvtAputPrimitive(cUnit, callInst, kWord, 2);
2997 break;
2998 case greenland::IntrinsicHelper::HLArrayPutObject:
2999 cvtAputObj(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07003000 break;
3001 case greenland::IntrinsicHelper::HLArrayPutWide:
3002 case greenland::IntrinsicHelper::HLArrayPutDouble:
buzbeef1f86362012-07-10 15:18:31 -07003003 cvtAputPrimitive(cUnit, callInst, kLong, 3);
buzbee8fa0fda2012-06-27 15:44:52 -07003004 break;
3005 case greenland::IntrinsicHelper::HLArrayPutBoolean:
buzbeef1f86362012-07-10 15:18:31 -07003006 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
buzbee8fa0fda2012-06-27 15:44:52 -07003007 break;
3008 case greenland::IntrinsicHelper::HLArrayPutByte:
buzbeef1f86362012-07-10 15:18:31 -07003009 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
buzbee8fa0fda2012-06-27 15:44:52 -07003010 break;
3011 case greenland::IntrinsicHelper::HLArrayPutChar:
buzbeef1f86362012-07-10 15:18:31 -07003012 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
buzbee8fa0fda2012-06-27 15:44:52 -07003013 break;
3014 case greenland::IntrinsicHelper::HLArrayPutShort:
buzbeef1f86362012-07-10 15:18:31 -07003015 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
buzbee8fa0fda2012-06-27 15:44:52 -07003016 break;
3017
buzbee101305f2012-06-28 18:00:56 -07003018 case greenland::IntrinsicHelper::HLIGet:
3019 case greenland::IntrinsicHelper::HLIGetFloat:
3020 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3021 break;
3022 case greenland::IntrinsicHelper::HLIGetObject:
3023 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3024 break;
3025 case greenland::IntrinsicHelper::HLIGetWide:
3026 case greenland::IntrinsicHelper::HLIGetDouble:
3027 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3028 break;
3029 case greenland::IntrinsicHelper::HLIGetBoolean:
3030 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3031 false /* obj */);
3032 break;
3033 case greenland::IntrinsicHelper::HLIGetByte:
3034 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3035 false /* obj */);
3036 break;
3037 case greenland::IntrinsicHelper::HLIGetChar:
3038 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3039 false /* obj */);
3040 break;
3041 case greenland::IntrinsicHelper::HLIGetShort:
3042 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3043 false /* obj */);
3044 break;
3045
3046 case greenland::IntrinsicHelper::HLIPut:
3047 case greenland::IntrinsicHelper::HLIPutFloat:
3048 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3049 break;
3050 case greenland::IntrinsicHelper::HLIPutObject:
3051 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3052 break;
3053 case greenland::IntrinsicHelper::HLIPutWide:
3054 case greenland::IntrinsicHelper::HLIPutDouble:
3055 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3056 break;
3057 case greenland::IntrinsicHelper::HLIPutBoolean:
3058 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3059 false /* obj */);
3060 break;
3061 case greenland::IntrinsicHelper::HLIPutByte:
3062 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3063 false /* obj */);
3064 break;
3065 case greenland::IntrinsicHelper::HLIPutChar:
3066 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3067 false /* obj */);
3068 break;
3069 case greenland::IntrinsicHelper::HLIPutShort:
3070 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3071 false /* obj */);
3072 break;
3073
3074 case greenland::IntrinsicHelper::IntToChar:
3075 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3076 break;
3077 case greenland::IntrinsicHelper::IntToShort:
3078 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3079 break;
3080 case greenland::IntrinsicHelper::IntToByte:
3081 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3082 break;
3083
buzbee76592632012-06-29 15:18:35 -07003084 case greenland::IntrinsicHelper::CmplFloat:
3085 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3086 break;
3087 case greenland::IntrinsicHelper::CmpgFloat:
3088 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3089 break;
3090 case greenland::IntrinsicHelper::CmplDouble:
3091 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3092 break;
3093 case greenland::IntrinsicHelper::CmpgDouble:
3094 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3095 break;
3096
3097 case greenland::IntrinsicHelper::CmpLong:
3098 cvtLongCompare(cUnit, callInst);
3099 break;
3100
buzbee2cfc6392012-05-07 14:51:40 -07003101 case greenland::IntrinsicHelper::UnknownId:
3102 cvtCall(cUnit, callInst, callee);
3103 break;
3104 default:
3105 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3106 << cUnit->intrinsic_helper->GetName(id);
3107 }
3108 }
3109 break;
3110
3111 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3112 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3113 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3114 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3115 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3116 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3117 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3118 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3119 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
buzbee101305f2012-06-28 18:00:56 -07003120 case llvm::Instruction::Shl: cvtShiftOp(cUnit, kOpLsl, inst); break;
3121 case llvm::Instruction::LShr: cvtShiftOp(cUnit, kOpLsr, inst); break;
3122 case llvm::Instruction::AShr: cvtShiftOp(cUnit, kOpAsr, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003123 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3124 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
buzbee4f1181f2012-06-22 13:52:12 -07003125 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3126 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3127 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3128 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3129 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
buzbee76592632012-06-29 15:18:35 -07003130 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
3131 case llvm::Instruction::FPToSI: cvtFPToInt(cUnit, inst); break;
3132 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3133 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3134 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003135
buzbee101305f2012-06-28 18:00:56 -07003136 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3137 break;
3138 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3139 break;
3140
buzbeef58c12c2012-07-03 15:06:29 -07003141 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3142
buzbee32412962012-06-26 16:27:56 -07003143 case llvm::Instruction::Unreachable:
3144 break; // FIXME: can we really ignore these?
3145
buzbee2cfc6392012-05-07 14:51:40 -07003146 case llvm::Instruction::Invoke:
buzbee2cfc6392012-05-07 14:51:40 -07003147 case llvm::Instruction::FPToUI:
buzbee2cfc6392012-05-07 14:51:40 -07003148 case llvm::Instruction::UIToFP:
buzbee2cfc6392012-05-07 14:51:40 -07003149 case llvm::Instruction::PtrToInt:
3150 case llvm::Instruction::IntToPtr:
buzbee2cfc6392012-05-07 14:51:40 -07003151 case llvm::Instruction::FCmp:
buzbee2cfc6392012-05-07 14:51:40 -07003152 case llvm::Instruction::URem:
3153 case llvm::Instruction::UDiv:
3154 case llvm::Instruction::Resume:
buzbee2cfc6392012-05-07 14:51:40 -07003155 case llvm::Instruction::Alloca:
3156 case llvm::Instruction::GetElementPtr:
3157 case llvm::Instruction::Fence:
3158 case llvm::Instruction::AtomicCmpXchg:
3159 case llvm::Instruction::AtomicRMW:
3160 case llvm::Instruction::BitCast:
3161 case llvm::Instruction::VAArg:
3162 case llvm::Instruction::Select:
3163 case llvm::Instruction::UserOp1:
3164 case llvm::Instruction::UserOp2:
3165 case llvm::Instruction::ExtractElement:
3166 case llvm::Instruction::InsertElement:
3167 case llvm::Instruction::ShuffleVector:
3168 case llvm::Instruction::ExtractValue:
3169 case llvm::Instruction::InsertValue:
3170 case llvm::Instruction::LandingPad:
3171 case llvm::Instruction::IndirectBr:
3172 case llvm::Instruction::Load:
3173 case llvm::Instruction::Store:
3174 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3175
3176 default:
3177 LOG(FATAL) << "Unknown llvm opcode: " << opcode; break;
3178 }
3179 }
buzbee6969d502012-06-15 16:40:31 -07003180
3181 if (headLIR != NULL) {
3182 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
3183 }
buzbee2cfc6392012-05-07 14:51:40 -07003184 return false;
3185}
3186
3187/*
3188 * Convert LLVM_IR to MIR:
3189 * o Iterate through the LLVM_IR and construct a graph using
3190 * standard MIR building blocks.
3191 * o Perform a basic-block optimization pass to remove unnecessary
3192 * store/load sequences.
3193 * o Convert the LLVM Value operands into RegLocations where applicable.
3194 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3195 * o Perform register promotion
3196 * o Iterate through the graph a basic block at a time, generating
3197 * LIR.
3198 * o Assemble LIR as usual.
3199 * o Profit.
3200 */
3201void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3202{
buzbeead8f15e2012-06-18 14:49:45 -07003203 llvm::Function* func = cUnit->func;
3204 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003205 // Allocate a list for LIR basic block labels
3206 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07003207 (LIR*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3208 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003209 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003210 for (llvm::Function::iterator i = func->begin(),
3211 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003212 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3213 &labelList[nextLabel++]);
3214 }
buzbeead8f15e2012-06-18 14:49:45 -07003215
3216 /*
3217 * Keep honest - clear regLocations, Value => RegLocation,
3218 * promotion map and VmapTables.
3219 */
3220 cUnit->locMap.clear(); // Start fresh
3221 cUnit->regLocation = NULL;
3222 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3223 i++) {
3224 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3225 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3226 }
3227 cUnit->coreSpillMask = 0;
3228 cUnit->numCoreSpills = 0;
3229 cUnit->fpSpillMask = 0;
3230 cUnit->numFPSpills = 0;
3231 cUnit->coreVmapTable.clear();
3232 cUnit->fpVmapTable.clear();
3233 oatAdjustSpillMask(cUnit);
3234 cUnit->frameSize = oatComputeFrameSize(cUnit);
3235
3236 /*
3237 * At this point, we've lost all knowledge of register promotion.
3238 * Rebuild that info from the MethodInfo intrinsic (if it
3239 * exists - not required for correctness).
3240 */
3241 // TODO: find and recover MethodInfo.
3242
3243 // Create RegLocations for arguments
3244 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3245 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3246 for (; it != it_end; ++it) {
3247 llvm::Value* val = it;
3248 createLocFromValue(cUnit, val);
3249 }
3250 // Create RegLocations for all non-argument defintions
3251 for (llvm::inst_iterator i = llvm::inst_begin(func),
3252 e = llvm::inst_end(func); i != e; ++i) {
3253 llvm::Value* val = &*i;
3254 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3255 createLocFromValue(cUnit, val);
3256 }
3257 }
3258
buzbee2cfc6392012-05-07 14:51:40 -07003259 // Walk the blocks, generating code.
3260 for (llvm::Function::iterator i = cUnit->func->begin(),
3261 e = cUnit->func->end(); i != e; ++i) {
3262 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3263 }
3264
3265 handleSuspendLaunchpads(cUnit);
3266
3267 handleThrowLaunchpads(cUnit);
3268
3269 handleIntrinsicLaunchpads(cUnit);
3270
3271 freeIR(cUnit);
3272}
3273
3274
3275} // namespace art
3276
3277#endif // ART_USE_QUICK_COMPILER