blob: 3ec4a1100e3048fc75452e6d2264f3e003e2d1a9 [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
buzbee2a83e8f2012-07-13 16:42:30 -0700467void convertShift(CompilationUnit* cUnit,
468 greenland::IntrinsicHelper::IntrinsicId id,
469 RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
buzbee4f1181f2012-06-22 13:52:12 -0700470{
buzbee2a83e8f2012-07-13 16:42:30 -0700471 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
472 llvm::SmallVector<llvm::Value*, 2>args;
473 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
474 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
475 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
476 defineValue(cUnit, res, rlDest.origSReg);
477}
478
479void convertShiftLit(CompilationUnit* cUnit,
480 greenland::IntrinsicHelper::IntrinsicId id,
481 RegLocation rlDest, RegLocation rlSrc, int shiftAmount)
482{
483 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
484 llvm::SmallVector<llvm::Value*, 2>args;
485 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
486 args.push_back(cUnit->irb->getInt32(shiftAmount));
487 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700488 defineValue(cUnit, res, rlDest.origSReg);
489}
490
buzbee2cfc6392012-05-07 14:51:40 -0700491void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
492 RegLocation rlSrc1, RegLocation rlSrc2)
493{
494 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
495 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700496 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700497 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
498 defineValue(cUnit, res, rlDest.origSReg);
499}
500
buzbeeb03f4872012-06-11 15:22:11 -0700501void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
502{
503 int index = -1;
504 DCHECK(newVal != NULL);
505 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
506 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
507 if (cUnit->shadowMap[i] == vReg) {
508 index = i;
509 break;
510 }
511 }
Elliott Hughes74847412012-06-20 18:10:21 -0700512 DCHECK_NE(index, -1) << "Corrupt shadowMap";
buzbeeb03f4872012-06-11 15:22:11 -0700513 greenland::IntrinsicHelper::IntrinsicId id =
514 greenland::IntrinsicHelper::SetShadowFrameEntry;
515 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
516 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
517 llvm::Value* args[] = { newVal, tableSlot };
518 cUnit->irb->CreateCall(func, args);
519}
520
buzbee2cfc6392012-05-07 14:51:40 -0700521void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
522 RegLocation rlSrc1, int32_t imm)
523{
524 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
525 llvm::Value* src2 = cUnit->irb->getInt32(imm);
526 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
527 defineValue(cUnit, res, rlDest.origSReg);
528}
529
buzbee101305f2012-06-28 18:00:56 -0700530/*
531 * Process arguments for invoke. Note: this code is also used to
532 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
533 * The requirements are similar.
534 */
buzbee6969d502012-06-15 16:40:31 -0700535void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700536 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700537{
538 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
539 llvm::SmallVector<llvm::Value*, 10> args;
540 // Insert the invokeType
541 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
542 // Insert the method_idx
543 args.push_back(cUnit->irb->getInt32(info->index));
544 // Insert the optimization flags
545 args.push_back(cUnit->irb->getInt32(info->optFlags));
546 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700547 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700548 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
549 args.push_back(val);
550 i += info->args[i].wide ? 2 : 1;
551 }
552 /*
553 * Choose the invoke return type based on actual usage. Note: may
554 * be different than shorty. For example, if a function return value
555 * is not used, we'll treat this as a void invoke.
556 */
557 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700558 if (isFilledNewArray) {
559 id = greenland::IntrinsicHelper::FilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700560 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700561 id = greenland::IntrinsicHelper::HLInvokeVoid;
562 } else {
563 if (info->result.wide) {
564 if (info->result.fp) {
565 id = greenland::IntrinsicHelper::HLInvokeDouble;
566 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700567 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700568 }
569 } else if (info->result.ref) {
570 id = greenland::IntrinsicHelper::HLInvokeObj;
571 } else if (info->result.fp) {
572 id = greenland::IntrinsicHelper::HLInvokeFloat;
573 } else {
574 id = greenland::IntrinsicHelper::HLInvokeInt;
575 }
576 }
577 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
578 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
579 if (info->result.location != kLocInvalid) {
580 defineValue(cUnit, res, info->result.origSReg);
581 }
582}
583
buzbee101305f2012-06-28 18:00:56 -0700584void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
585 greenland::IntrinsicHelper::IntrinsicId id,
586 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700587{
buzbee6969d502012-06-15 16:40:31 -0700588 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700589 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700590 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
591 defineValue(cUnit, res, rlDest.origSReg);
592}
593
buzbee101305f2012-06-28 18:00:56 -0700594void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
595 RegLocation rlSrc)
596{
597 greenland::IntrinsicHelper::IntrinsicId id;
598 id = greenland::IntrinsicHelper::CheckCast;
599 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
600 llvm::SmallVector<llvm::Value*, 2> args;
601 args.push_back(cUnit->irb->getInt32(type_idx));
602 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
603 cUnit->irb->CreateCall(intr, args);
604}
605
buzbee8fa0fda2012-06-27 15:44:52 -0700606void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
607 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700608{
609 greenland::IntrinsicHelper::IntrinsicId id;
610 id = greenland::IntrinsicHelper::NewInstance;
611 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
612 llvm::Value* index = cUnit->irb->getInt32(type_idx);
613 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
614 defineValue(cUnit, res, rlDest.origSReg);
615}
616
buzbee8fa0fda2012-06-27 15:44:52 -0700617void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
618 RegLocation rlDest, RegLocation rlSrc)
619{
620 greenland::IntrinsicHelper::IntrinsicId id;
621 id = greenland::IntrinsicHelper::NewArray;
622 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
623 llvm::SmallVector<llvm::Value*, 2> args;
624 args.push_back(cUnit->irb->getInt32(type_idx));
625 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
626 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
627 defineValue(cUnit, res, rlDest.origSReg);
628}
629
630void convertAget(CompilationUnit* cUnit, int optFlags,
631 greenland::IntrinsicHelper::IntrinsicId id,
632 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
633{
634 llvm::SmallVector<llvm::Value*, 3> args;
635 args.push_back(cUnit->irb->getInt32(optFlags));
636 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
637 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
638 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
639 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
640 defineValue(cUnit, res, rlDest.origSReg);
641}
642
643void convertAput(CompilationUnit* cUnit, int optFlags,
644 greenland::IntrinsicHelper::IntrinsicId id,
645 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
646{
647 llvm::SmallVector<llvm::Value*, 4> args;
648 args.push_back(cUnit->irb->getInt32(optFlags));
649 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
650 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
651 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
652 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
653 cUnit->irb->CreateCall(intr, args);
654}
655
buzbee101305f2012-06-28 18:00:56 -0700656void convertIget(CompilationUnit* cUnit, int optFlags,
657 greenland::IntrinsicHelper::IntrinsicId id,
658 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
659{
660 llvm::SmallVector<llvm::Value*, 3> args;
661 args.push_back(cUnit->irb->getInt32(optFlags));
662 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
663 args.push_back(cUnit->irb->getInt32(fieldIndex));
664 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
665 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
666 defineValue(cUnit, res, rlDest.origSReg);
667}
668
669void convertIput(CompilationUnit* cUnit, int optFlags,
670 greenland::IntrinsicHelper::IntrinsicId id,
671 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
672{
673 llvm::SmallVector<llvm::Value*, 4> args;
674 args.push_back(cUnit->irb->getInt32(optFlags));
675 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
676 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
677 args.push_back(cUnit->irb->getInt32(fieldIndex));
678 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
679 cUnit->irb->CreateCall(intr, args);
680}
681
buzbee8fa0fda2012-06-27 15:44:52 -0700682void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
683 RegLocation rlDest, RegLocation rlSrc)
684{
685 greenland::IntrinsicHelper::IntrinsicId id;
686 id = greenland::IntrinsicHelper::InstanceOf;
687 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
688 llvm::SmallVector<llvm::Value*, 2> args;
689 args.push_back(cUnit->irb->getInt32(type_idx));
690 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
691 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
692 defineValue(cUnit, res, rlDest.origSReg);
693}
694
buzbee101305f2012-06-28 18:00:56 -0700695void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
696 RegLocation rlSrc)
697{
698 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
699 cUnit->irb->getInt64Ty());
700 defineValue(cUnit, res, rlDest.origSReg);
701}
702
buzbee76592632012-06-29 15:18:35 -0700703void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
704 RegLocation rlSrc)
705{
706 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
707 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
708 defineValue(cUnit, res, rlDest.origSReg);
709}
710
711void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
712 RegLocation rlSrc)
713{
714 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
715 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
716 defineValue(cUnit, res, rlDest.origSReg);
717}
718
719void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
720 RegLocation rlSrc)
721{
722 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
723 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
724 defineValue(cUnit, res, rlDest.origSReg);
725}
726
727void convertWideComparison(CompilationUnit* cUnit,
728 greenland::IntrinsicHelper::IntrinsicId id,
729 RegLocation rlDest, RegLocation rlSrc1,
730 RegLocation rlSrc2)
731{
732 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
733 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
734 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
735 llvm::SmallVector<llvm::Value*, 2> args;
736 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
737 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
738 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
739 defineValue(cUnit, res, rlDest.origSReg);
740}
741
buzbee101305f2012-06-28 18:00:56 -0700742void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
743 RegLocation rlSrc,
744 greenland::IntrinsicHelper::IntrinsicId id)
745{
746 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700747 llvm::Value* res =
748 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
749 defineValue(cUnit, res, rlDest.origSReg);
750}
751
752void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
753 RegLocation rlSrc)
754{
755 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
756 defineValue(cUnit, res, rlDest.origSReg);
757}
758
759void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
760 RegLocation rlSrc)
761{
762 llvm::Value* res =
763 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
764 defineValue(cUnit, res, rlDest.origSReg);
765}
766
767void convertFPToInt(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
768 RegLocation rlSrc)
769{
770 llvm::Value* res =
771 cUnit->irb->CreateFPToSI(getLLVMValue(cUnit, rlSrc.origSReg), ty);
772 defineValue(cUnit, res, rlDest.origSReg);
773}
774
775
776void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
777 RegLocation rlSrc)
778{
779 llvm::Value* res =
780 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
781 defineValue(cUnit, res, rlDest.origSReg);
782}
783
784void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
785 RegLocation rlSrc)
786{
787 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
788 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700789 defineValue(cUnit, res, rlDest.origSReg);
790}
791
buzbee2cfc6392012-05-07 14:51:40 -0700792/*
793 * Target-independent code generation. Use only high-level
794 * load/store utilities here, or target-dependent genXX() handlers
795 * when necessary.
796 */
797bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
798 llvm::BasicBlock* llvmBB, LIR* labelList)
799{
800 bool res = false; // Assume success
801 RegLocation rlSrc[3];
802 RegLocation rlDest = badLoc;
803 RegLocation rlResult = badLoc;
804 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee32412962012-06-26 16:27:56 -0700805 uint32_t vA = mir->dalvikInsn.vA;
buzbee6969d502012-06-15 16:40:31 -0700806 uint32_t vB = mir->dalvikInsn.vB;
807 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700808 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700809
buzbeeb03f4872012-06-11 15:22:11 -0700810 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700811
812 /* Prep Src and Dest locations */
813 int nextSreg = 0;
814 int nextLoc = 0;
815 int attrs = oatDataFlowAttributes[opcode];
816 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
817 if (attrs & DF_UA) {
818 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700819 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700820 nextSreg+= 2;
821 } else {
822 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
823 nextSreg++;
824 }
825 }
826 if (attrs & DF_UB) {
827 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700828 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700829 nextSreg+= 2;
830 } else {
831 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
832 nextSreg++;
833 }
834 }
835 if (attrs & DF_UC) {
836 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700837 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700838 } else {
839 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
840 }
841 }
842 if (attrs & DF_DA) {
843 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700844 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700845 } else {
buzbee15bf9802012-06-12 17:49:27 -0700846 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700847 if (rlDest.ref) {
848 objectDefinition = true;
849 }
buzbee2cfc6392012-05-07 14:51:40 -0700850 }
851 }
852
853 switch (opcode) {
854 case Instruction::NOP:
855 break;
856
857 case Instruction::MOVE:
858 case Instruction::MOVE_OBJECT:
859 case Instruction::MOVE_16:
860 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700861 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700862 case Instruction::MOVE_FROM16:
863 case Instruction::MOVE_WIDE:
864 case Instruction::MOVE_WIDE_16:
865 case Instruction::MOVE_WIDE_FROM16: {
866 /*
867 * Moves/copies are meaningless in pure SSA register form,
868 * but we need to preserve them for the conversion back into
869 * MIR (at least until we stop using the Dalvik register maps).
870 * Insert a dummy intrinsic copy call, which will be recognized
871 * by the quick path and removed by the portable path.
872 */
873 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
874 llvm::Value* res = emitCopy(cUnit, src, rlDest);
875 defineValue(cUnit, res, rlDest.origSReg);
876 }
877 break;
878
879 case Instruction::CONST:
880 case Instruction::CONST_4:
881 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700882 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700883 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
884 defineValue(cUnit, res, rlDest.origSReg);
885 }
886 break;
887
888 case Instruction::CONST_WIDE_16:
889 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700890 // Sign extend to 64 bits
891 int64_t imm = static_cast<int32_t>(vB);
892 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700893 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
894 defineValue(cUnit, res, rlDest.origSReg);
895 }
896 break;
897
898 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700899 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700900 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
901 defineValue(cUnit, res, rlDest.origSReg);
902 }
903 break;
904
905 case Instruction::CONST_WIDE: {
906 llvm::Constant* immValue =
907 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
908 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
909 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700910 }
911 break;
buzbee2cfc6392012-05-07 14:51:40 -0700912 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700913 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700914 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
915 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
916 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700917 }
918 break;
919
buzbee8fa0fda2012-06-27 15:44:52 -0700920 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700921 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700922 rlSrc[0]);
923 break;
924 case Instruction::SPUT:
925 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700926 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700927 rlSrc[0]);
928 } else {
buzbee76592632012-06-29 15:18:35 -0700929 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700930 }
931 break;
932 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700933 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700934 rlSrc[0]);
935 break;
936 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700937 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700938 break;
939 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700940 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700941 break;
942 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -0700943 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700944 break;
945 case Instruction::SPUT_WIDE:
946 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700947 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -0700948 rlSrc[0]);
949 } else {
buzbee76592632012-06-29 15:18:35 -0700950 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -0700951 rlSrc[0]);
952 }
953 break;
954
955 case Instruction::SGET_OBJECT:
956 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
957 break;
958 case Instruction::SGET:
959 if (rlDest.fp) {
960 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
961 } else {
962 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
963 }
964 break;
965 case Instruction::SGET_BOOLEAN:
966 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
967 break;
968 case Instruction::SGET_BYTE:
969 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
970 break;
971 case Instruction::SGET_CHAR:
972 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
973 break;
974 case Instruction::SGET_SHORT:
975 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
976 break;
977 case Instruction::SGET_WIDE:
978 if (rlDest.fp) {
979 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
980 rlDest);
981 } else {
982 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -0700983 }
984 break;
buzbee2cfc6392012-05-07 14:51:40 -0700985
986 case Instruction::RETURN_WIDE:
987 case Instruction::RETURN:
988 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -0700989 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700990 emitSuspendCheck(cUnit);
991 }
buzbeeb03f4872012-06-11 15:22:11 -0700992 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700993 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
994 bb->hasReturn = true;
995 }
996 break;
997
998 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -0700999 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001000 emitSuspendCheck(cUnit);
1001 }
buzbeeb03f4872012-06-11 15:22:11 -07001002 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001003 cUnit->irb->CreateRetVoid();
1004 bb->hasReturn = true;
1005 }
1006 break;
1007
1008 case Instruction::IF_EQ:
1009 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1010 break;
1011 case Instruction::IF_NE:
1012 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1013 break;
1014 case Instruction::IF_LT:
1015 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1016 break;
1017 case Instruction::IF_GE:
1018 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1019 break;
1020 case Instruction::IF_GT:
1021 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1022 break;
1023 case Instruction::IF_LE:
1024 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1025 break;
1026 case Instruction::IF_EQZ:
1027 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1028 break;
1029 case Instruction::IF_NEZ:
1030 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1031 break;
1032 case Instruction::IF_LTZ:
1033 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1034 break;
1035 case Instruction::IF_GEZ:
1036 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1037 break;
1038 case Instruction::IF_GTZ:
1039 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1040 break;
1041 case Instruction::IF_LEZ:
1042 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1043 break;
1044
1045 case Instruction::GOTO:
1046 case Instruction::GOTO_16:
1047 case Instruction::GOTO_32: {
1048 if (bb->taken->startOffset <= bb->startOffset) {
1049 emitSuspendCheck(cUnit);
1050 }
1051 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1052 }
1053 break;
1054
1055 case Instruction::ADD_LONG:
1056 case Instruction::ADD_LONG_2ADDR:
1057 case Instruction::ADD_INT:
1058 case Instruction::ADD_INT_2ADDR:
1059 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1060 break;
1061 case Instruction::SUB_LONG:
1062 case Instruction::SUB_LONG_2ADDR:
1063 case Instruction::SUB_INT:
1064 case Instruction::SUB_INT_2ADDR:
1065 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1066 break;
1067 case Instruction::MUL_LONG:
1068 case Instruction::MUL_LONG_2ADDR:
1069 case Instruction::MUL_INT:
1070 case Instruction::MUL_INT_2ADDR:
1071 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1072 break;
1073 case Instruction::DIV_LONG:
1074 case Instruction::DIV_LONG_2ADDR:
1075 case Instruction::DIV_INT:
1076 case Instruction::DIV_INT_2ADDR:
1077 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1078 break;
1079 case Instruction::REM_LONG:
1080 case Instruction::REM_LONG_2ADDR:
1081 case Instruction::REM_INT:
1082 case Instruction::REM_INT_2ADDR:
1083 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1084 break;
1085 case Instruction::AND_LONG:
1086 case Instruction::AND_LONG_2ADDR:
1087 case Instruction::AND_INT:
1088 case Instruction::AND_INT_2ADDR:
1089 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1090 break;
1091 case Instruction::OR_LONG:
1092 case Instruction::OR_LONG_2ADDR:
1093 case Instruction::OR_INT:
1094 case Instruction::OR_INT_2ADDR:
1095 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1096 break;
1097 case Instruction::XOR_LONG:
1098 case Instruction::XOR_LONG_2ADDR:
1099 case Instruction::XOR_INT:
1100 case Instruction::XOR_INT_2ADDR:
1101 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1102 break;
1103 case Instruction::SHL_LONG:
1104 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001105 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1106 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001107 break;
buzbee2cfc6392012-05-07 14:51:40 -07001108 case Instruction::SHL_INT:
1109 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001110 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1111 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001112 break;
1113 case Instruction::SHR_LONG:
1114 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001115 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1116 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001117 break;
buzbee2cfc6392012-05-07 14:51:40 -07001118 case Instruction::SHR_INT:
1119 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001120 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1121 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001122 break;
1123 case Instruction::USHR_LONG:
1124 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001125 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1126 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001127 break;
buzbee2cfc6392012-05-07 14:51:40 -07001128 case Instruction::USHR_INT:
1129 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001130 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1131 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001132 break;
1133
1134 case Instruction::ADD_INT_LIT16:
1135 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001136 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001137 break;
1138 case Instruction::RSUB_INT:
1139 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001140 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001141 break;
1142 case Instruction::MUL_INT_LIT16:
1143 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001144 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001145 break;
1146 case Instruction::DIV_INT_LIT16:
1147 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001148 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001149 break;
1150 case Instruction::REM_INT_LIT16:
1151 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001152 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001153 break;
1154 case Instruction::AND_INT_LIT16:
1155 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001156 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001157 break;
1158 case Instruction::OR_INT_LIT16:
1159 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001160 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001161 break;
1162 case Instruction::XOR_INT_LIT16:
1163 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001164 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001165 break;
1166 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001167 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1168 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001169 break;
1170 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001171 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1172 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001173 break;
1174 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001175 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1176 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001177 break;
1178
1179 case Instruction::ADD_FLOAT:
1180 case Instruction::ADD_FLOAT_2ADDR:
1181 case Instruction::ADD_DOUBLE:
1182 case Instruction::ADD_DOUBLE_2ADDR:
1183 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1184 break;
1185
1186 case Instruction::SUB_FLOAT:
1187 case Instruction::SUB_FLOAT_2ADDR:
1188 case Instruction::SUB_DOUBLE:
1189 case Instruction::SUB_DOUBLE_2ADDR:
1190 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1191 break;
1192
1193 case Instruction::MUL_FLOAT:
1194 case Instruction::MUL_FLOAT_2ADDR:
1195 case Instruction::MUL_DOUBLE:
1196 case Instruction::MUL_DOUBLE_2ADDR:
1197 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1198 break;
1199
1200 case Instruction::DIV_FLOAT:
1201 case Instruction::DIV_FLOAT_2ADDR:
1202 case Instruction::DIV_DOUBLE:
1203 case Instruction::DIV_DOUBLE_2ADDR:
1204 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1205 break;
1206
1207 case Instruction::REM_FLOAT:
1208 case Instruction::REM_FLOAT_2ADDR:
1209 case Instruction::REM_DOUBLE:
1210 case Instruction::REM_DOUBLE_2ADDR:
1211 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1212 break;
1213
buzbee6969d502012-06-15 16:40:31 -07001214 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001215 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1216 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001217 break;
1218 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001219 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1220 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001221 break;
1222
1223 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001224 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1225 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001226 break;
1227 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001228 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1229 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001230 break;
1231
1232 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001233 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1234 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001235 break;
1236 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001237 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1238 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001239 break;
1240
1241 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001242 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1243 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001244 break;
1245 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001246 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1247 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001248 break;
1249
1250 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001251 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1252 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001253 break;
1254 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001255 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1256 false /* NewFilledArray */);
1257 break;
1258 case Instruction::FILLED_NEW_ARRAY:
1259 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1260 true /* NewFilledArray */);
1261 break;
1262 case Instruction::FILLED_NEW_ARRAY_RANGE:
1263 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1264 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001265 break;
1266
1267 case Instruction::CONST_STRING:
1268 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001269 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1270 rlDest);
1271 break;
1272
1273 case Instruction::CONST_CLASS:
1274 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1275 rlDest);
1276 break;
1277
1278 case Instruction::CHECK_CAST:
1279 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001280 break;
1281
buzbee4f1181f2012-06-22 13:52:12 -07001282 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001283 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001284 break;
1285
buzbee32412962012-06-26 16:27:56 -07001286 case Instruction::MOVE_EXCEPTION:
1287 convertMoveException(cUnit, rlDest);
1288 break;
1289
1290 case Instruction::THROW:
1291 convertThrow(cUnit, rlSrc[0]);
1292 break;
1293
1294 case Instruction::THROW_VERIFICATION_ERROR:
1295 convertThrowVerificationError(cUnit, vA, vB);
1296 break;
buzbee6969d502012-06-15 16:40:31 -07001297
buzbee2cfc6392012-05-07 14:51:40 -07001298 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001299 case Instruction::MOVE_RESULT:
1300 case Instruction::MOVE_RESULT_OBJECT:
buzbee85eee022012-07-16 22:12:38 -07001301#if defined(TARGET_ARM)
buzbee8fa0fda2012-06-27 15:44:52 -07001302 CHECK(false) << "Unexpected MOVE_RESULT";
buzbee85eee022012-07-16 22:12:38 -07001303#else
1304 UNIMPLEMENTED(WARNING) << "need x86 move-result fusing";
1305#endif
1306
buzbee2cfc6392012-05-07 14:51:40 -07001307 break;
1308
1309 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001310 convertMonitorEnterExit(cUnit, optFlags,
1311 greenland::IntrinsicHelper::MonitorEnter,
1312 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001313 break;
1314
1315 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001316 convertMonitorEnterExit(cUnit, optFlags,
1317 greenland::IntrinsicHelper::MonitorExit,
1318 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001319 break;
1320
1321 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001322 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001323 break;
1324
1325 case Instruction::NEW_ARRAY:
1326 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1327 break;
1328
1329 case Instruction::INSTANCE_OF:
1330 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1331 break;
1332
1333 case Instruction::AGET:
1334 if (rlDest.fp) {
1335 convertAget(cUnit, optFlags,
1336 greenland::IntrinsicHelper::HLArrayGetFloat,
1337 rlDest, rlSrc[0], rlSrc[1]);
1338 } else {
1339 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1340 rlDest, rlSrc[0], rlSrc[1]);
1341 }
1342 break;
1343 case Instruction::AGET_OBJECT:
1344 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1345 rlDest, rlSrc[0], rlSrc[1]);
1346 break;
1347 case Instruction::AGET_BOOLEAN:
1348 convertAget(cUnit, optFlags,
1349 greenland::IntrinsicHelper::HLArrayGetBoolean,
1350 rlDest, rlSrc[0], rlSrc[1]);
1351 break;
1352 case Instruction::AGET_BYTE:
1353 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1354 rlDest, rlSrc[0], rlSrc[1]);
1355 break;
1356 case Instruction::AGET_CHAR:
1357 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1358 rlDest, rlSrc[0], rlSrc[1]);
1359 break;
1360 case Instruction::AGET_SHORT:
1361 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1362 rlDest, rlSrc[0], rlSrc[1]);
1363 break;
1364 case Instruction::AGET_WIDE:
1365 if (rlDest.fp) {
1366 convertAget(cUnit, optFlags,
1367 greenland::IntrinsicHelper::HLArrayGetDouble,
1368 rlDest, rlSrc[0], rlSrc[1]);
1369 } else {
1370 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1371 rlDest, rlSrc[0], rlSrc[1]);
1372 }
1373 break;
1374
1375 case Instruction::APUT:
1376 if (rlSrc[0].fp) {
1377 convertAput(cUnit, optFlags,
1378 greenland::IntrinsicHelper::HLArrayPutFloat,
1379 rlSrc[0], rlSrc[1], rlSrc[2]);
1380 } else {
1381 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1382 rlSrc[0], rlSrc[1], rlSrc[2]);
1383 }
1384 break;
1385 case Instruction::APUT_OBJECT:
1386 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1387 rlSrc[0], rlSrc[1], rlSrc[2]);
1388 break;
1389 case Instruction::APUT_BOOLEAN:
1390 convertAput(cUnit, optFlags,
1391 greenland::IntrinsicHelper::HLArrayPutBoolean,
1392 rlSrc[0], rlSrc[1], rlSrc[2]);
1393 break;
1394 case Instruction::APUT_BYTE:
1395 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1396 rlSrc[0], rlSrc[1], rlSrc[2]);
1397 break;
1398 case Instruction::APUT_CHAR:
1399 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1400 rlSrc[0], rlSrc[1], rlSrc[2]);
1401 break;
1402 case Instruction::APUT_SHORT:
1403 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1404 rlSrc[0], rlSrc[1], rlSrc[2]);
1405 break;
1406 case Instruction::APUT_WIDE:
1407 if (rlSrc[0].fp) {
1408 convertAput(cUnit, optFlags,
1409 greenland::IntrinsicHelper::HLArrayPutDouble,
1410 rlSrc[0], rlSrc[1], rlSrc[2]);
1411 } else {
1412 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1413 rlSrc[0], rlSrc[1], rlSrc[2]);
1414 }
1415 break;
1416
buzbee101305f2012-06-28 18:00:56 -07001417 case Instruction::IGET:
1418 if (rlDest.fp) {
1419 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001420 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001421 } else {
1422 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001423 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001424 }
buzbee2cfc6392012-05-07 14:51:40 -07001425 break;
buzbee101305f2012-06-28 18:00:56 -07001426 case Instruction::IGET_OBJECT:
1427 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001428 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001429 break;
1430 case Instruction::IGET_BOOLEAN:
1431 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001432 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001433 break;
1434 case Instruction::IGET_BYTE:
1435 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001436 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001437 break;
1438 case Instruction::IGET_CHAR:
1439 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001440 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001441 break;
1442 case Instruction::IGET_SHORT:
1443 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001444 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001445 break;
1446 case Instruction::IGET_WIDE:
1447 if (rlDest.fp) {
1448 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001449 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001450 } else {
1451 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001452 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001453 }
1454 break;
1455 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001456 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001457 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1458 rlSrc[0], rlSrc[1], vC);
1459 } else {
1460 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1461 rlSrc[0], rlSrc[1], vC);
1462 }
1463 break;
1464 case Instruction::IPUT_OBJECT:
1465 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1466 rlSrc[0], rlSrc[1], vC);
1467 break;
1468 case Instruction::IPUT_BOOLEAN:
1469 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1470 rlSrc[0], rlSrc[1], vC);
1471 break;
1472 case Instruction::IPUT_BYTE:
1473 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1474 rlSrc[0], rlSrc[1], vC);
1475 break;
1476 case Instruction::IPUT_CHAR:
1477 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1478 rlSrc[0], rlSrc[1], vC);
1479 break;
1480 case Instruction::IPUT_SHORT:
1481 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1482 rlSrc[0], rlSrc[1], vC);
1483 break;
1484 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001485 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001486 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1487 rlSrc[0], rlSrc[1], vC);
1488 } else {
1489 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1490 rlSrc[0], rlSrc[1], vC);
1491 }
buzbee2cfc6392012-05-07 14:51:40 -07001492 break;
1493
1494 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001495 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001496 break;
1497
buzbee76592632012-06-29 15:18:35 -07001498 case Instruction::LONG_TO_INT:
1499 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1500 break;
1501
buzbee101305f2012-06-28 18:00:56 -07001502 case Instruction::INT_TO_LONG:
1503 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001504 break;
1505
buzbee101305f2012-06-28 18:00:56 -07001506 case Instruction::INT_TO_CHAR:
1507 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1508 greenland::IntrinsicHelper::IntToChar);
1509 break;
1510 case Instruction::INT_TO_BYTE:
1511 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1512 greenland::IntrinsicHelper::IntToByte);
1513 break;
1514 case Instruction::INT_TO_SHORT:
1515 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1516 greenland::IntrinsicHelper::IntToShort);
1517 break;
1518
buzbee76592632012-06-29 15:18:35 -07001519 case Instruction::INT_TO_FLOAT:
1520 case Instruction::LONG_TO_FLOAT:
1521 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001522 break;
1523
buzbee76592632012-06-29 15:18:35 -07001524 case Instruction::INT_TO_DOUBLE:
1525 case Instruction::LONG_TO_DOUBLE:
1526 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001527 break;
1528
buzbee76592632012-06-29 15:18:35 -07001529 case Instruction::FLOAT_TO_DOUBLE:
1530 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001531 break;
1532
buzbee76592632012-06-29 15:18:35 -07001533 case Instruction::DOUBLE_TO_FLOAT:
1534 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001535 break;
1536
1537 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001538 case Instruction::NEG_INT:
1539 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001540 break;
1541
1542 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001543 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001544 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001545 break;
1546
buzbee76592632012-06-29 15:18:35 -07001547 case Instruction::NOT_LONG:
1548 case Instruction::NOT_INT:
1549 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001550 break;
1551
buzbee2cfc6392012-05-07 14:51:40 -07001552 case Instruction::FLOAT_TO_INT:
buzbee2cfc6392012-05-07 14:51:40 -07001553 case Instruction::DOUBLE_TO_INT:
buzbee76592632012-06-29 15:18:35 -07001554 convertFPToInt(cUnit, cUnit->irb->getInt32Ty(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001555 break;
1556
buzbee76592632012-06-29 15:18:35 -07001557 case Instruction::FLOAT_TO_LONG:
1558 case Instruction::DOUBLE_TO_LONG:
1559 convertFPToInt(cUnit, cUnit->irb->getInt64Ty(), rlDest, rlSrc[0]);
1560 break;
1561
1562 case Instruction::CMPL_FLOAT:
1563 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1564 rlDest, rlSrc[0], rlSrc[1]);
1565 break;
1566 case Instruction::CMPG_FLOAT:
1567 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1568 rlDest, rlSrc[0], rlSrc[1]);
1569 break;
1570 case Instruction::CMPL_DOUBLE:
1571 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1572 rlDest, rlSrc[0], rlSrc[1]);
1573 break;
1574 case Instruction::CMPG_DOUBLE:
1575 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1576 rlDest, rlSrc[0], rlSrc[1]);
1577 break;
1578 case Instruction::CMP_LONG:
1579 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1580 rlDest, rlSrc[0], rlSrc[1]);
1581 break;
1582
buzbee76592632012-06-29 15:18:35 -07001583 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001584 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001585 break;
1586
1587 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001588 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001589 break;
buzbee2cfc6392012-05-07 14:51:40 -07001590
1591 default:
buzbee32412962012-06-26 16:27:56 -07001592 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001593 res = true;
1594 }
buzbeeb03f4872012-06-11 15:22:11 -07001595 if (objectDefinition) {
1596 setShadowFrameEntry(cUnit, (llvm::Value*)
1597 cUnit->llvmValues.elemList[rlDest.origSReg]);
1598 }
buzbee2cfc6392012-05-07 14:51:40 -07001599 return res;
1600}
1601
1602/* Extended MIR instructions like PHI */
1603void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1604 llvm::BasicBlock* llvmBB)
1605{
1606
1607 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1608 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001609 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001610 /*
1611 * The Art compiler's Phi nodes only handle 32-bit operands,
1612 * representing wide values using a matched set of Phi nodes
1613 * for the lower and upper halves. In the llvm world, we only
1614 * want a single Phi for wides. Here we will simply discard
1615 * the Phi node representing the high word.
1616 */
1617 if (rlDest.highWord) {
1618 return; // No Phi node - handled via low word
1619 }
1620 int* incoming = (int*)mir->dalvikInsn.vB;
buzbee2cfc6392012-05-07 14:51:40 -07001621 llvm::Type* phiType =
1622 llvmTypeFromLocRec(cUnit, rlDest);
1623 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1624 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1625 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001626 // Don't check width here.
1627 loc = oatGetRawSrc(cUnit, mir, i);
1628 DCHECK_EQ(rlDest.wide, loc.wide);
1629 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1630 DCHECK_EQ(rlDest.fp, loc.fp);
1631 DCHECK_EQ(rlDest.core, loc.core);
1632 DCHECK_EQ(rlDest.ref, loc.ref);
buzbee2cfc6392012-05-07 14:51:40 -07001633 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
1634 getLLVMBlock(cUnit, incoming[i]));
1635 }
1636 defineValue(cUnit, phi, rlDest.origSReg);
1637 break;
1638 }
1639 case kMirOpCopy: {
1640 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1641 break;
1642 }
1643#if defined(TARGET_ARM)
1644 case kMirOpFusedCmplFloat:
1645 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1646 break;
1647 case kMirOpFusedCmpgFloat:
1648 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1649 break;
1650 case kMirOpFusedCmplDouble:
1651 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1652 break;
1653 case kMirOpFusedCmpgDouble:
1654 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1655 break;
1656 case kMirOpFusedCmpLong:
1657 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1658 break;
1659#endif
1660 default:
1661 break;
1662 }
1663}
1664
1665void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1666{
1667 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001668 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001669 arrayRef.push_back(cUnit->irb->getInt32(offset));
1670 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1671 cUnit->irb->SetDexOffset(node);
1672}
1673
1674// Attach method info as metadata to special intrinsic
1675void setMethodInfo(CompilationUnit* cUnit)
1676{
1677 // We don't want dex offset on this
1678 cUnit->irb->SetDexOffset(NULL);
1679 greenland::IntrinsicHelper::IntrinsicId id;
1680 id = greenland::IntrinsicHelper::MethodInfo;
1681 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1682 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1683 llvm::SmallVector<llvm::Value*, 2> regInfo;
1684 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1685 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1686 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1687 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1688 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1689 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1690 inst->setMetadata("RegInfo", regInfoNode);
1691 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1692 llvm::SmallVector<llvm::Value*, 50> pmap;
1693 for (int i = 0; i < promoSize; i++) {
1694 PromotionMap* p = &cUnit->promotionMap[i];
1695 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1696 ((p->fpReg & 0xff) << 16) |
1697 ((p->coreReg & 0xff) << 8) |
1698 ((p->fpLocation & 0xf) << 4) |
1699 (p->coreLocation & 0xf);
1700 pmap.push_back(cUnit->irb->getInt32(mapData));
1701 }
1702 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1703 inst->setMetadata("PromotionMap", mapNode);
1704 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1705}
1706
1707/* Handle the content in each basic block */
1708bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1709{
1710 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1711 cUnit->irb->SetInsertPoint(llvmBB);
1712 setDexOffset(cUnit, bb->startOffset);
1713
1714 if (bb->blockType == kEntryBlock) {
1715 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001716 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1717 cUnit->numDalvikRegisters, true,
1718 kAllocMisc);
1719 for (int i = 0; i < cUnit->numSSARegs; i++) {
1720 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1721 }
1722 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1723 if (canBeRef[i]) {
1724 cUnit->numShadowFrameEntries++;
1725 }
1726 }
1727 if (cUnit->numShadowFrameEntries > 0) {
1728 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1729 cUnit->numShadowFrameEntries, true,
1730 kAllocMisc);
1731 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1732 if (canBeRef[i]) {
1733 cUnit->shadowMap[j++] = i;
1734 }
1735 }
1736 greenland::IntrinsicHelper::IntrinsicId id =
1737 greenland::IntrinsicHelper::AllocaShadowFrame;
1738 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1739 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1740 cUnit->irb->CreateCall(func, entries);
1741 }
buzbee2cfc6392012-05-07 14:51:40 -07001742 } else if (bb->blockType == kExitBlock) {
1743 /*
1744 * Because of the differences between how MIR/LIR and llvm handle exit
1745 * blocks, we won't explicitly covert them. On the llvm-to-lir
1746 * path, it will need to be regenereated.
1747 */
1748 return false;
buzbee6969d502012-06-15 16:40:31 -07001749 } else if (bb->blockType == kExceptionHandling) {
1750 /*
1751 * Because we're deferring null checking, delete the associated empty
1752 * exception block.
1753 * TODO: add new block type for exception blocks that we generate
1754 * greenland code for.
1755 */
1756 llvmBB->eraseFromParent();
1757 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001758 }
1759
1760 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1761
1762 setDexOffset(cUnit, mir->offset);
1763
1764 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
1765 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
1766
1767 /* If we're compiling for the debugger, generate an update callout */
1768 if (cUnit->genDebugger) {
1769 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1770 //genDebuggerUpdate(cUnit, mir->offset);
1771 }
1772
1773 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
1774 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1775 continue;
1776 }
1777
1778 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1779 NULL /* labelList */);
1780 if (notHandled) {
1781 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
1782 mir->offset, dalvikOpcode,
1783 Instruction::Name(dalvikOpcode),
1784 dalvikFormat);
1785 }
1786 }
1787
buzbee4be777b2012-07-12 14:38:18 -07001788 if (bb->blockType == kEntryBlock) {
1789 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1790 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001791 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1792 }
1793
1794 return false;
1795}
1796
buzbee4f4dfc72012-07-02 14:54:44 -07001797char remapShorty(char shortyType) {
1798 /*
1799 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1800 * and longs/doubles are represented as a pair of registers. When sub-word
1801 * arguments (and method results) are passed, they are extended to Dalvik
1802 * virtual register containers. Because llvm is picky about type consistency,
1803 * we must either cast the "real" type to 32-bit container multiple Dalvik
1804 * register types, or always use the expanded values.
1805 * Here, we're doing the latter. We map the shorty signature to container
1806 * types (which is valid so long as we always do a real expansion of passed
1807 * arguments and field loads).
1808 */
1809 switch(shortyType) {
1810 case 'Z' : shortyType = 'I'; break;
1811 case 'B' : shortyType = 'I'; break;
1812 case 'S' : shortyType = 'I'; break;
1813 case 'C' : shortyType = 'I'; break;
1814 default: break;
1815 }
1816 return shortyType;
1817}
1818
buzbee2cfc6392012-05-07 14:51:40 -07001819llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1820
1821 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001822 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001823 greenland::kAccurate);
1824
1825 // Get argument type
1826 std::vector<llvm::Type*> args_type;
1827
1828 // method object
1829 args_type.push_back(cUnit->irb->GetJMethodTy());
1830
1831 // Do we have a "this"?
1832 if ((cUnit->access_flags & kAccStatic) == 0) {
1833 args_type.push_back(cUnit->irb->GetJObjectTy());
1834 }
1835
1836 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001837 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001838 greenland::kAccurate));
1839 }
1840
1841 return llvm::FunctionType::get(ret_type, args_type, false);
1842}
1843
1844bool createFunction(CompilationUnit* cUnit) {
1845 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1846 /* with_signature */ false));
1847 llvm::FunctionType* func_type = getFunctionType(cUnit);
1848
1849 if (func_type == NULL) {
1850 return false;
1851 }
1852
1853 cUnit->func = llvm::Function::Create(func_type,
1854 llvm::Function::ExternalLinkage,
1855 func_name, cUnit->module);
1856
1857 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1858 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1859
1860 arg_iter->setName("method");
1861 ++arg_iter;
1862
1863 int startSReg = cUnit->numRegs;
1864
1865 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1866 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1867 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1868 }
1869
1870 return true;
1871}
1872
1873bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1874{
1875 // Skip the exit block
1876 if (bb->blockType == kExitBlock) {
1877 cUnit->idToBlockMap.Put(bb->id, NULL);
1878 } else {
1879 int offset = bb->startOffset;
1880 bool entryBlock = (bb->blockType == kEntryBlock);
1881 llvm::BasicBlock* llvmBB =
1882 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
Elliott Hughes74847412012-06-20 18:10:21 -07001883 StringPrintf(kLabelFormat, offset, bb->id),
buzbee2cfc6392012-05-07 14:51:40 -07001884 cUnit->func);
1885 if (entryBlock) {
1886 cUnit->entryBB = llvmBB;
1887 cUnit->placeholderBB =
1888 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1889 cUnit->func);
1890 }
1891 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1892 }
1893 return false;
1894}
1895
1896
1897/*
1898 * Convert MIR to LLVM_IR
1899 * o For each ssa name, create LLVM named value. Type these
1900 * appropriately, and ignore high half of wide and double operands.
1901 * o For each MIR basic block, create an LLVM basic block.
1902 * o Iterate through the MIR a basic block at a time, setting arguments
1903 * to recovered ssa name.
1904 */
1905void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
1906{
1907 initIR(cUnit);
1908 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
1909
1910 // Create the function
1911 createFunction(cUnit);
1912
1913 // Create an LLVM basic block for each MIR block in dfs preorder
1914 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
1915 kPreOrderDFSTraversal, false /* isIterative */);
1916 /*
1917 * Create an llvm named value for each MIR SSA name. Note: we'll use
1918 * placeholders for all non-argument values (because we haven't seen
1919 * the definition yet).
1920 */
1921 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
1922 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1923 arg_iter++; /* Skip path method */
1924 for (int i = 0; i < cUnit->numSSARegs; i++) {
1925 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07001926 RegLocation rlTemp = cUnit->regLocation[i];
1927 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07001928 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1929 } else if ((i < cUnit->numRegs) ||
1930 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07001931 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
1932 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07001933 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
1934 val->setName(llvmSSAName(cUnit, i));
buzbee2cfc6392012-05-07 14:51:40 -07001935 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
buzbee2cfc6392012-05-07 14:51:40 -07001936 } else {
1937 // Recover previously-created argument values
1938 llvm::Value* argVal = arg_iter++;
1939 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
1940 }
1941 }
buzbee2cfc6392012-05-07 14:51:40 -07001942
1943 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
1944 kPreOrderDFSTraversal, false /* Iterative */);
1945
buzbee4be777b2012-07-12 14:38:18 -07001946 /*
1947 * In a few rare cases of verification failure, the verifier will
1948 * replace one or more Dalvik opcodes with the special
1949 * throw-verification-failure opcode. This can leave the SSA graph
1950 * in an invalid state, as definitions may be lost, while uses retained.
1951 * To work around this problem, we insert placeholder definitions for
1952 * all Dalvik SSA regs in the "placeholder" block. Here, after
1953 * bitcode conversion is complete, we examine those placeholder definitions
1954 * and delete any with no references (which normally is all of them).
1955 *
1956 * If any definitions remain, we link the placeholder block into the
1957 * CFG. Otherwise, it is deleted.
1958 */
1959 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
1960 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
1961 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
1962 DCHECK(inst != NULL);
1963 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
1964 DCHECK(val != NULL);
1965 if (val->getNumUses() == 0) {
1966 inst->eraseFromParent();
1967 }
1968 }
1969 setDexOffset(cUnit, 0);
1970 if (cUnit->placeholderBB->empty()) {
1971 cUnit->placeholderBB->eraseFromParent();
1972 } else {
1973 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
1974 cUnit->irb->CreateBr(cUnit->entryTargetBB);
1975 cUnit->entryTargetBB = cUnit->placeholderBB;
1976 }
1977 cUnit->irb->SetInsertPoint(cUnit->entryBB);
1978 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07001979
buzbee2a83e8f2012-07-13 16:42:30 -07001980 //llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction);
buzbee2cfc6392012-05-07 14:51:40 -07001981
buzbeead8f15e2012-06-18 14:49:45 -07001982 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
1983 // Write bitcode to file
1984 std::string errmsg;
1985 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
1986 oatReplaceSpecialChars(fname);
1987 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07001988 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07001989
buzbeead8f15e2012-06-18 14:49:45 -07001990 llvm::OwningPtr<llvm::tool_output_file> out_file(
1991 new llvm::tool_output_file(fname.c_str(), errmsg,
1992 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07001993
buzbeead8f15e2012-06-18 14:49:45 -07001994 if (!errmsg.empty()) {
1995 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
1996 }
1997
1998 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
1999 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002000 }
buzbee2cfc6392012-05-07 14:51:40 -07002001}
2002
2003RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2004 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002005 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002006 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2007 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002008 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002009 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002010 // FIXME: need to be more robust, handle FP and be in a position to
2011 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002012 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2013 memset(&res, 0, sizeof(res));
2014 res.location = kLocPhysReg;
2015 res.lowReg = oatAllocTemp(cUnit);
2016 res.home = true;
2017 res.sRegLow = INVALID_SREG;
2018 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002019 llvm::Type* ty = val->getType();
2020 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2021 (ty == cUnit->irb->getDoubleTy()));
2022 if (res.wide) {
2023 res.highReg = oatAllocTemp(cUnit);
2024 }
buzbee4f1181f2012-06-22 13:52:12 -07002025 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002026 } else {
2027 DCHECK_EQ(valName[0], 'v');
2028 int baseSReg = INVALID_SREG;
2029 sscanf(valName.c_str(), "v%d_", &baseSReg);
2030 res = cUnit->regLocation[baseSReg];
2031 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002032 }
2033 } else {
2034 res = it->second;
2035 }
2036 return res;
2037}
2038
2039Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2040{
2041 Instruction::Code res = Instruction::NOP;
2042 if (isWide) {
2043 switch(op) {
2044 case kOpAdd: res = Instruction::ADD_LONG; break;
2045 case kOpSub: res = Instruction::SUB_LONG; break;
2046 case kOpMul: res = Instruction::MUL_LONG; break;
2047 case kOpDiv: res = Instruction::DIV_LONG; break;
2048 case kOpRem: res = Instruction::REM_LONG; break;
2049 case kOpAnd: res = Instruction::AND_LONG; break;
2050 case kOpOr: res = Instruction::OR_LONG; break;
2051 case kOpXor: res = Instruction::XOR_LONG; break;
2052 case kOpLsl: res = Instruction::SHL_LONG; break;
2053 case kOpLsr: res = Instruction::USHR_LONG; break;
2054 case kOpAsr: res = Instruction::SHR_LONG; break;
2055 default: LOG(FATAL) << "Unexpected OpKind " << op;
2056 }
2057 } else if (isConst){
2058 switch(op) {
2059 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2060 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2061 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2062 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2063 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2064 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2065 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2066 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2067 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2068 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2069 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2070 default: LOG(FATAL) << "Unexpected OpKind " << op;
2071 }
2072 } else {
2073 switch(op) {
2074 case kOpAdd: res = Instruction::ADD_INT; break;
2075 case kOpSub: res = Instruction::SUB_INT; break;
2076 case kOpMul: res = Instruction::MUL_INT; break;
2077 case kOpDiv: res = Instruction::DIV_INT; break;
2078 case kOpRem: res = Instruction::REM_INT; break;
2079 case kOpAnd: res = Instruction::AND_INT; break;
2080 case kOpOr: res = Instruction::OR_INT; break;
2081 case kOpXor: res = Instruction::XOR_INT; break;
2082 case kOpLsl: res = Instruction::SHL_INT; break;
2083 case kOpLsr: res = Instruction::USHR_INT; break;
2084 case kOpAsr: res = Instruction::SHR_INT; break;
2085 default: LOG(FATAL) << "Unexpected OpKind " << op;
2086 }
2087 }
2088 return res;
2089}
2090
buzbee4f1181f2012-06-22 13:52:12 -07002091Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2092{
2093 Instruction::Code res = Instruction::NOP;
2094 if (isWide) {
2095 switch(op) {
2096 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2097 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2098 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2099 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2100 case kOpRem: res = Instruction::REM_DOUBLE; break;
2101 default: LOG(FATAL) << "Unexpected OpKind " << op;
2102 }
2103 } else {
2104 switch(op) {
2105 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2106 case kOpSub: res = Instruction::SUB_FLOAT; break;
2107 case kOpMul: res = Instruction::MUL_FLOAT; break;
2108 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2109 case kOpRem: res = Instruction::REM_FLOAT; break;
2110 default: LOG(FATAL) << "Unexpected OpKind " << op;
2111 }
2112 }
2113 return res;
2114}
2115
2116void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2117{
2118 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002119 /*
2120 * Normally, we won't ever generate an FP operation with an immediate
2121 * operand (not supported in Dex instruction set). However, the IR builder
2122 * may insert them - in particular for createNegFP. Recognize this case
2123 * and deal with it.
2124 */
2125 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2126 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2127 DCHECK(op2C == NULL);
2128 if ((op1C != NULL) && (op == kOpSub)) {
2129 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2130 if (rlDest.wide) {
2131 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2132 } else {
2133 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2134 }
buzbee4f1181f2012-06-22 13:52:12 -07002135 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002136 DCHECK(op1C == NULL);
2137 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2138 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2139 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2140 if (rlDest.wide) {
2141 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2142 } else {
2143 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2144 }
buzbee4f1181f2012-06-22 13:52:12 -07002145 }
2146}
2147
buzbee101305f2012-06-28 18:00:56 -07002148void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2149 Instruction::Code opcode)
2150{
2151 RegLocation rlDest = getLoc(cUnit, inst);
2152 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2153 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2154}
2155
buzbee76592632012-06-29 15:18:35 -07002156void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2157{
2158 RegLocation rlDest = getLoc(cUnit, inst);
2159 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2160 Instruction::Code opcode;
2161 if (rlDest.wide) {
2162 if (rlSrc.wide) {
2163 opcode = Instruction::LONG_TO_DOUBLE;
2164 } else {
2165 opcode = Instruction::INT_TO_DOUBLE;
2166 }
2167 } else {
2168 if (rlSrc.wide) {
2169 opcode = Instruction::LONG_TO_FLOAT;
2170 } else {
2171 opcode = Instruction::INT_TO_FLOAT;
2172 }
2173 }
2174 genConversion(cUnit, opcode, rlDest, rlSrc);
2175}
2176
2177void cvtFPToInt(CompilationUnit* cUnit, llvm::Instruction* inst)
2178{
2179 RegLocation rlDest = getLoc(cUnit, inst);
2180 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2181 Instruction::Code opcode;
2182 if (rlDest.wide) {
2183 if (rlSrc.wide) {
2184 opcode = Instruction::DOUBLE_TO_LONG;
2185 } else {
2186 opcode = Instruction::FLOAT_TO_LONG;
2187 }
2188 } else {
2189 if (rlSrc.wide) {
2190 opcode = Instruction::DOUBLE_TO_INT;
2191 } else {
2192 opcode = Instruction::FLOAT_TO_INT;
2193 }
2194 }
2195 genConversion(cUnit, opcode, rlDest, rlSrc);
2196}
2197
2198void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2199{
2200 RegLocation rlDest = getLoc(cUnit, inst);
2201 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2202 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2203}
2204
2205void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2206{
2207 RegLocation rlDest = getLoc(cUnit, inst);
2208 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2209 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2210 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2211 storeValue(cUnit, rlDest, rlSrc);
2212}
2213
2214void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2215{
2216 RegLocation rlDest = getLoc(cUnit, inst);
2217 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2218 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2219}
2220
2221
buzbee101305f2012-06-28 18:00:56 -07002222void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2223{
2224 // TODO: evaluate src/tgt types and add general support for more than int to long
2225 RegLocation rlDest = getLoc(cUnit, inst);
2226 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2227 DCHECK(rlDest.wide);
2228 DCHECK(!rlSrc.wide);
2229 DCHECK(!rlDest.fp);
2230 DCHECK(!rlSrc.fp);
2231 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2232 if (rlSrc.location == kLocPhysReg) {
2233 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2234 } else {
2235 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2236 }
2237 if (isSigned) {
2238 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2239 } else {
2240 loadConstant(cUnit, rlResult.highReg, 0);
2241 }
2242 storeValueWide(cUnit, rlDest, rlResult);
2243}
2244
buzbee2cfc6392012-05-07 14:51:40 -07002245void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2246{
2247 RegLocation rlDest = getLoc(cUnit, inst);
2248 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002249 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002250 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2251 if ((op == kOpSub) && (lhsImm != NULL)) {
2252 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002253 if (rlSrc1.wide) {
2254 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2255 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2256 } else {
2257 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2258 lhsImm->getSExtValue());
2259 }
buzbee4f1181f2012-06-22 13:52:12 -07002260 return;
2261 }
2262 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002263 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2264 llvm::Value* rhs = inst->getOperand(1);
2265 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2266 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
2267 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, src2->getSExtValue());
2268 } else {
2269 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
2270 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2271 if (rlDest.wide) {
2272 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2273 } else {
2274 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2275 }
2276 }
2277}
2278
buzbee2a83e8f2012-07-13 16:42:30 -07002279void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2280 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002281{
buzbee2a83e8f2012-07-13 16:42:30 -07002282 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2283 RegLocation rlDest = getLoc(cUnit, callInst);
2284 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2285 llvm::Value* rhs = callInst->getArgOperand(1);
2286 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2287 DCHECK(!rlDest.wide);
2288 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002289 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002290 RegLocation rlShift = getLoc(cUnit, rhs);
2291 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2292 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2293 } else {
2294 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2295 }
buzbee101305f2012-06-28 18:00:56 -07002296 }
2297}
2298
buzbee2cfc6392012-05-07 14:51:40 -07002299void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2300{
2301 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2302 DCHECK(brInst != NULL);
2303 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2304 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2305 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2306}
2307
2308void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2309{
2310 // Nop - these have already been processed
2311}
2312
2313void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2314{
2315 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2316 llvm::Value* retVal = retInst->getReturnValue();
2317 if (retVal != NULL) {
2318 RegLocation rlSrc = getLoc(cUnit, retVal);
2319 if (rlSrc.wide) {
2320 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2321 } else {
2322 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2323 }
2324 }
2325 genExitSequence(cUnit);
2326}
2327
2328ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2329{
2330 ConditionCode res = kCondAl;
2331 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002332 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002333 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2334 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2335 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002336 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002337 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002338 default: LOG(FATAL) << "Unexpected llvm condition";
2339 }
2340 return res;
2341}
2342
2343void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2344{
2345 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2346 UNIMPLEMENTED(FATAL);
2347}
2348
2349void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2350 llvm::BranchInst* brInst)
2351{
2352 // Get targets
2353 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2354 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2355 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2356 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2357 // Get comparison operands
2358 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2359 ConditionCode cond = getCond(iCmpInst->getPredicate());
2360 llvm::Value* lhs = iCmpInst->getOperand(0);
2361 // Not expecting a constant as 1st operand
2362 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2363 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2364 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2365 llvm::Value* rhs = inst->getOperand(1);
2366#if defined(TARGET_MIPS)
2367 // Compare and branch in one shot
2368 (void)taken;
2369 (void)cond;
2370 (void)rhs;
2371 UNIMPLEMENTED(FATAL);
2372#else
2373 //Compare, then branch
2374 // TODO: handle fused CMP_LONG/IF_xxZ case
2375 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2376 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002377 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2378 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002379 } else {
2380 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2381 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2382 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2383 }
2384 opCondBranch(cUnit, cond, taken);
2385#endif
2386 // Fallthrough
2387 opUnconditionalBranch(cUnit, fallThrough);
2388}
2389
2390void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2391 llvm::Function* callee)
2392{
2393 UNIMPLEMENTED(FATAL);
2394}
2395
buzbee2cfc6392012-05-07 14:51:40 -07002396void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2397{
buzbee4f1181f2012-06-22 13:52:12 -07002398 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002399 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2400 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002401 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2402 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002403 if (rlSrc.wide) {
2404 storeValueWide(cUnit, rlDest, rlSrc);
2405 } else {
2406 storeValue(cUnit, rlDest, rlSrc);
2407 }
2408}
2409
2410// Note: Immediate arg is a ConstantInt regardless of result type
2411void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2412{
buzbee4f1181f2012-06-22 13:52:12 -07002413 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002414 llvm::ConstantInt* src =
2415 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2416 uint64_t immval = src->getZExtValue();
2417 RegLocation rlDest = getLoc(cUnit, callInst);
2418 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2419 if (rlDest.wide) {
2420 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2421 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2422 storeValueWide(cUnit, rlDest, rlResult);
2423 } else {
2424 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2425 storeValue(cUnit, rlDest, rlResult);
2426 }
2427}
2428
buzbee101305f2012-06-28 18:00:56 -07002429void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2430 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002431{
buzbee4f1181f2012-06-22 13:52:12 -07002432 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002433 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002434 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002435 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002436 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002437 if (isString) {
2438 genConstString(cUnit, index, rlDest);
2439 } else {
2440 genConstClass(cUnit, index, rlDest);
2441 }
2442}
2443
2444void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2445{
2446 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2447 llvm::ConstantInt* offsetVal =
2448 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2449 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2450 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002451}
2452
buzbee4f1181f2012-06-22 13:52:12 -07002453void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2454{
buzbee32412962012-06-26 16:27:56 -07002455 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002456 llvm::ConstantInt* typeIdxVal =
2457 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2458 uint32_t typeIdx = typeIdxVal->getZExtValue();
2459 RegLocation rlDest = getLoc(cUnit, callInst);
2460 genNewInstance(cUnit, typeIdx, rlDest);
2461}
2462
buzbee8fa0fda2012-06-27 15:44:52 -07002463void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2464{
2465 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2466 llvm::ConstantInt* typeIdxVal =
2467 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2468 uint32_t typeIdx = typeIdxVal->getZExtValue();
2469 llvm::Value* len = callInst->getArgOperand(1);
2470 RegLocation rlLen = getLoc(cUnit, len);
2471 RegLocation rlDest = getLoc(cUnit, callInst);
2472 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2473}
2474
2475void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2476{
2477 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2478 llvm::ConstantInt* typeIdxVal =
2479 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2480 uint32_t typeIdx = typeIdxVal->getZExtValue();
2481 llvm::Value* src = callInst->getArgOperand(1);
2482 RegLocation rlSrc = getLoc(cUnit, src);
2483 RegLocation rlDest = getLoc(cUnit, callInst);
2484 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2485}
2486
buzbee32412962012-06-26 16:27:56 -07002487void cvtThrowVerificationError(CompilationUnit* cUnit, llvm::CallInst* callInst)
2488{
2489 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2490 llvm::ConstantInt* info1 =
2491 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2492 llvm::ConstantInt* info2 =
2493 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2494 genThrowVerificationError(cUnit, info1->getZExtValue(), info2->getZExtValue());
2495}
2496
2497void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2498{
2499 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2500 llvm::Value* src = callInst->getArgOperand(0);
2501 RegLocation rlSrc = getLoc(cUnit, src);
2502 genThrow(cUnit, rlSrc);
2503}
2504
buzbee8fa0fda2012-06-27 15:44:52 -07002505void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2506 llvm::CallInst* callInst)
2507{
2508 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2509 llvm::ConstantInt* optFlags =
2510 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2511 llvm::Value* src = callInst->getArgOperand(1);
2512 RegLocation rlSrc = getLoc(cUnit, src);
2513 if (isEnter) {
2514 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2515 } else {
2516 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2517 }
2518}
2519
buzbee76592632012-06-29 15:18:35 -07002520void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002521{
2522 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2523 llvm::ConstantInt* optFlags =
2524 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2525 llvm::Value* src = callInst->getArgOperand(1);
2526 RegLocation rlSrc = getLoc(cUnit, src);
2527 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2528 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2529 RegLocation rlDest = getLoc(cUnit, callInst);
2530 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2531 int lenOffset = Array::LengthOffset().Int32Value();
2532 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2533 storeValue(cUnit, rlDest, rlResult);
2534}
2535
buzbee32412962012-06-26 16:27:56 -07002536void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2537{
2538 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
2539 int exOffset = Thread::ExceptionOffset().Int32Value();
2540 RegLocation rlDest = getLoc(cUnit, callInst);
2541 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2542#if defined(TARGET_X86)
2543 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
2544 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
2545#else
2546 int resetReg = oatAllocTemp(cUnit);
2547 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
2548 loadConstant(cUnit, resetReg, 0);
2549 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
2550 oatFreeTemp(cUnit, resetReg);
2551#endif
2552 storeValue(cUnit, rlDest, rlResult);
2553}
2554
buzbee4f1181f2012-06-22 13:52:12 -07002555void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2556 bool isObject)
2557{
buzbee32412962012-06-26 16:27:56 -07002558 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002559 llvm::ConstantInt* typeIdxVal =
2560 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2561 uint32_t typeIdx = typeIdxVal->getZExtValue();
2562 RegLocation rlDest = getLoc(cUnit, callInst);
2563 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2564}
2565
buzbee8fa0fda2012-06-27 15:44:52 -07002566void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2567 bool isObject)
2568{
2569 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2570 llvm::ConstantInt* typeIdxVal =
2571 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2572 uint32_t typeIdx = typeIdxVal->getZExtValue();
2573 llvm::Value* src = callInst->getArgOperand(1);
2574 RegLocation rlSrc = getLoc(cUnit, src);
2575 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2576}
2577
2578void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2579 int scale)
2580{
2581 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2582 llvm::ConstantInt* optFlags =
2583 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2584 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2585 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2586 RegLocation rlDest = getLoc(cUnit, callInst);
2587 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2588 rlDest, scale);
2589}
2590
2591void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002592 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002593{
2594 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2595 llvm::ConstantInt* optFlags =
2596 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2597 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2598 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2599 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002600 if (isObject) {
2601 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2602 rlSrc, scale);
2603 } else {
2604 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2605 rlSrc, scale);
2606 }
2607}
2608
2609void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2610{
2611 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2612}
2613
2614void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2615 OpSize size, int scale)
2616{
2617 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002618}
2619
buzbee101305f2012-06-28 18:00:56 -07002620void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2621 bool isWide, bool isObj)
2622{
2623 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2624 llvm::ConstantInt* optFlags =
2625 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2626 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2627 llvm::ConstantInt* fieldIdx =
2628 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2629 RegLocation rlDest = getLoc(cUnit, callInst);
2630 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2631 size, rlDest, rlObj, isWide, isObj);
2632}
2633
2634void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2635 bool isWide, bool isObj)
2636{
2637 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2638 llvm::ConstantInt* optFlags =
2639 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2640 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2641 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2642 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002643 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002644 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2645 size, rlSrc, rlObj, isWide, isObj);
2646}
2647
2648void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2649{
2650 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2651 llvm::ConstantInt* typeIdx =
2652 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2653 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2654 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2655}
2656
buzbee76592632012-06-29 15:18:35 -07002657void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2658 Instruction::Code opcode)
2659{
2660 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2661 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2662 RegLocation rlDest = getLoc(cUnit, callInst);
2663 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2664}
2665
2666void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2667{
2668 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2669 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2670 RegLocation rlDest = getLoc(cUnit, callInst);
2671 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2672}
2673
buzbeef58c12c2012-07-03 15:06:29 -07002674void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2675{
2676 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2677 DCHECK(swInst != NULL);
2678 llvm::Value* testVal = swInst->getCondition();
2679 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2680 DCHECK(tableOffsetNode != NULL);
2681 llvm::ConstantInt* tableOffsetValue =
2682 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2683 int32_t tableOffset = tableOffsetValue->getSExtValue();
2684 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeea1da8a52012-07-09 14:00:21 -07002685 const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2686 u2 tableMagic = *table;
2687 if (tableMagic == 0x100) {
2688 genPackedSwitch(cUnit, tableOffset, rlSrc);
2689 } else {
2690 DCHECK_EQ(tableMagic, 0x200);
2691 genSparseSwitch(cUnit, tableOffset, rlSrc);
2692 }
buzbeef58c12c2012-07-03 15:06:29 -07002693}
2694
buzbee6969d502012-06-15 16:40:31 -07002695void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002696 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002697{
2698 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2699 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002700 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002701 info->result.location = kLocInvalid;
2702 } else {
2703 info->result = getLoc(cUnit, callInst);
2704 }
2705 llvm::ConstantInt* invokeTypeVal =
2706 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2707 llvm::ConstantInt* methodIndexVal =
2708 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2709 llvm::ConstantInt* optFlagsVal =
2710 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2711 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2712 info->index = methodIndexVal->getZExtValue();
2713 info->optFlags = optFlagsVal->getZExtValue();
2714 info->offset = cUnit->currentDalvikOffset;
2715
buzbee6969d502012-06-15 16:40:31 -07002716 // Count the argument words, and then build argument array.
2717 info->numArgWords = 0;
2718 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2719 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2720 info->numArgWords += tLoc.wide ? 2 : 1;
2721 }
2722 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2723 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2724 // Now, fill in the location records, synthesizing high loc of wide vals
2725 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002726 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002727 if (info->args[next].wide) {
2728 next++;
2729 // TODO: Might make sense to mark this as an invalid loc
2730 info->args[next].origSReg = info->args[next-1].origSReg+1;
2731 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2732 }
2733 next++;
2734 }
buzbee4f4dfc72012-07-02 14:54:44 -07002735 // TODO - rework such that we no longer need isRange
2736 info->isRange = (info->numArgWords > 5);
2737
buzbee76592632012-06-29 15:18:35 -07002738 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002739 genFilledNewArray(cUnit, info);
2740 } else {
2741 genInvoke(cUnit, info);
2742 }
buzbee6969d502012-06-15 16:40:31 -07002743}
2744
buzbeead8f15e2012-06-18 14:49:45 -07002745/* Look up the RegLocation associated with a Value. Must already be defined */
2746RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2747{
2748 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2749 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2750 return it->second;
2751}
2752
buzbee2cfc6392012-05-07 14:51:40 -07002753bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2754{
2755 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2756 // Define the starting label
2757 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2758 // Extract the starting offset from the block's name
2759 if (!isEntry) {
2760 const char* blockName = bb->getName().str().c_str();
2761 int dummy;
Elliott Hughes74847412012-06-20 18:10:21 -07002762 sscanf(blockName, kLabelFormat, &blockLabel->operands[0], &dummy);
buzbee2cfc6392012-05-07 14:51:40 -07002763 }
2764 // Set the label kind
2765 blockLabel->opcode = kPseudoNormalBlockLabel;
2766 // Insert the label
2767 oatAppendLIR(cUnit, blockLabel);
2768
2769 // Free temp registers and reset redundant store tracking */
2770 oatResetRegPool(cUnit);
2771 oatResetDefTracking(cUnit);
2772
2773 //TODO: restore oat incoming liveness optimization
2774 oatClobberAllRegs(cUnit);
2775
buzbee6969d502012-06-15 16:40:31 -07002776 LIR* headLIR = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07002777
2778 if (isEntry) {
2779 cUnit->currentDalvikOffset = 0;
buzbeead8f15e2012-06-18 14:49:45 -07002780 RegLocation* argLocs = (RegLocation*)
2781 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2782 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2783 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2784 for (unsigned i = 0; it != it_end; ++it) {
2785 llvm::Value* val = it;
2786 argLocs[i++] = valToLoc(cUnit, val);
2787 llvm::Type* ty = val->getType();
2788 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2789 argLocs[i++].sRegLow = INVALID_SREG;
2790 }
2791 }
2792 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
buzbee2cfc6392012-05-07 14:51:40 -07002793 }
2794
2795 // Visit all of the instructions in the block
2796 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2797 llvm::Instruction* inst = it;
2798 llvm::BasicBlock::iterator nextIt = ++it;
2799 // Extract the Dalvik offset from the instruction
2800 uint32_t opcode = inst->getOpcode();
2801 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2802 if (dexOffsetNode != NULL) {
2803 llvm::ConstantInt* dexOffsetValue =
2804 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2805 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2806 }
2807
buzbee6969d502012-06-15 16:40:31 -07002808 oatResetRegPool(cUnit);
2809 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2810 oatClobberAllRegs(cUnit);
2811 }
2812
2813 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2814 oatResetDefTracking(cUnit);
2815 }
2816
2817#ifndef NDEBUG
2818 /* Reset temp tracking sanity check */
2819 cUnit->liveSReg = INVALID_SREG;
2820#endif
2821
2822 LIR* boundaryLIR;
2823 const char* instStr = "boundary";
2824 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
2825 (intptr_t) instStr);
2826 cUnit->boundaryMap.Overwrite(cUnit->currentDalvikOffset, boundaryLIR);
2827
2828 /* Remember the first LIR for thisl block*/
2829 if (headLIR == NULL) {
2830 headLIR = boundaryLIR;
2831 headLIR->defMask = ENCODE_ALL;
2832 }
2833
buzbee2cfc6392012-05-07 14:51:40 -07002834 switch(opcode) {
2835
2836 case llvm::Instruction::ICmp: {
2837 llvm::Instruction* nextInst = nextIt;
2838 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2839 if (brInst != NULL /* and... */) {
2840 cvtICmpBr(cUnit, inst, brInst);
2841 ++it;
2842 } else {
2843 cvtICmp(cUnit, inst);
2844 }
2845 }
2846 break;
2847
2848 case llvm::Instruction::Call: {
2849 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2850 llvm::Function* callee = callInst->getCalledFunction();
2851 greenland::IntrinsicHelper::IntrinsicId id =
2852 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2853 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07002854 case greenland::IntrinsicHelper::AllocaShadowFrame:
2855 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07002856 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07002857 // Ignore shadow frame stuff for quick compiler
2858 break;
buzbee2cfc6392012-05-07 14:51:40 -07002859 case greenland::IntrinsicHelper::CopyInt:
2860 case greenland::IntrinsicHelper::CopyObj:
2861 case greenland::IntrinsicHelper::CopyFloat:
2862 case greenland::IntrinsicHelper::CopyLong:
2863 case greenland::IntrinsicHelper::CopyDouble:
2864 cvtCopy(cUnit, callInst);
2865 break;
2866 case greenland::IntrinsicHelper::ConstInt:
2867 case greenland::IntrinsicHelper::ConstObj:
2868 case greenland::IntrinsicHelper::ConstLong:
2869 case greenland::IntrinsicHelper::ConstFloat:
2870 case greenland::IntrinsicHelper::ConstDouble:
2871 cvtConst(cUnit, callInst);
2872 break;
buzbee4f1181f2012-06-22 13:52:12 -07002873 case greenland::IntrinsicHelper::DivInt:
2874 case greenland::IntrinsicHelper::DivLong:
2875 cvtBinOp(cUnit, kOpDiv, inst);
2876 break;
2877 case greenland::IntrinsicHelper::RemInt:
2878 case greenland::IntrinsicHelper::RemLong:
2879 cvtBinOp(cUnit, kOpRem, inst);
2880 break;
buzbee2cfc6392012-05-07 14:51:40 -07002881 case greenland::IntrinsicHelper::MethodInfo:
buzbeead8f15e2012-06-18 14:49:45 -07002882 // Already dealt with - just ignore it here.
buzbee2cfc6392012-05-07 14:51:40 -07002883 break;
2884 case greenland::IntrinsicHelper::CheckSuspend:
2885 genSuspendTest(cUnit, 0 /* optFlags already applied */);
2886 break;
buzbee4f1181f2012-06-22 13:52:12 -07002887 case greenland::IntrinsicHelper::HLInvokeObj:
buzbee8fa0fda2012-06-27 15:44:52 -07002888 case greenland::IntrinsicHelper::HLInvokeFloat:
2889 case greenland::IntrinsicHelper::HLInvokeDouble:
2890 case greenland::IntrinsicHelper::HLInvokeLong:
2891 case greenland::IntrinsicHelper::HLInvokeInt:
buzbee101305f2012-06-28 18:00:56 -07002892 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
buzbee4f1181f2012-06-22 13:52:12 -07002893 break;
buzbee6969d502012-06-15 16:40:31 -07002894 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbee101305f2012-06-28 18:00:56 -07002895 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
2896 break;
2897 case greenland::IntrinsicHelper::FilledNewArray:
2898 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
2899 break;
2900 case greenland::IntrinsicHelper::FillArrayData:
2901 cvtFillArrayData(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07002902 break;
2903 case greenland::IntrinsicHelper::ConstString:
buzbee101305f2012-06-28 18:00:56 -07002904 cvtConstObject(cUnit, callInst, true /* isString */);
2905 break;
2906 case greenland::IntrinsicHelper::ConstClass:
2907 cvtConstObject(cUnit, callInst, false /* isString */);
2908 break;
2909 case greenland::IntrinsicHelper::CheckCast:
2910 cvtCheckCast(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07002911 break;
buzbee4f1181f2012-06-22 13:52:12 -07002912 case greenland::IntrinsicHelper::NewInstance:
2913 cvtNewInstance(cUnit, callInst);
2914 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002915 case greenland::IntrinsicHelper::HLSgetObject:
buzbee4f1181f2012-06-22 13:52:12 -07002916 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
2917 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002918 case greenland::IntrinsicHelper::HLSget:
2919 case greenland::IntrinsicHelper::HLSgetFloat:
2920 case greenland::IntrinsicHelper::HLSgetBoolean:
2921 case greenland::IntrinsicHelper::HLSgetByte:
2922 case greenland::IntrinsicHelper::HLSgetChar:
2923 case greenland::IntrinsicHelper::HLSgetShort:
2924 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
2925 break;
2926 case greenland::IntrinsicHelper::HLSgetWide:
2927 case greenland::IntrinsicHelper::HLSgetDouble:
2928 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
2929 break;
buzbee76592632012-06-29 15:18:35 -07002930 case greenland::IntrinsicHelper::HLSput:
2931 case greenland::IntrinsicHelper::HLSputFloat:
2932 case greenland::IntrinsicHelper::HLSputBoolean:
2933 case greenland::IntrinsicHelper::HLSputByte:
2934 case greenland::IntrinsicHelper::HLSputChar:
2935 case greenland::IntrinsicHelper::HLSputShort:
2936 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
2937 break;
2938 case greenland::IntrinsicHelper::HLSputWide:
2939 case greenland::IntrinsicHelper::HLSputDouble:
2940 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
2941 break;
buzbeea1da8a52012-07-09 14:00:21 -07002942 case greenland::IntrinsicHelper::HLSputObject:
2943 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
2944 break;
buzbee32412962012-06-26 16:27:56 -07002945 case greenland::IntrinsicHelper::GetException:
2946 cvtMoveException(cUnit, callInst);
2947 break;
2948 case greenland::IntrinsicHelper::Throw:
2949 cvtThrow(cUnit, callInst);
2950 break;
2951 case greenland::IntrinsicHelper::ThrowVerificationError:
buzbee8fa0fda2012-06-27 15:44:52 -07002952 cvtThrowVerificationError(cUnit, callInst);
buzbee32412962012-06-26 16:27:56 -07002953 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002954 case greenland::IntrinsicHelper::MonitorEnter:
2955 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
2956 break;
2957 case greenland::IntrinsicHelper::MonitorExit:
2958 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
2959 break;
2960 case greenland::IntrinsicHelper::ArrayLength:
buzbee76592632012-06-29 15:18:35 -07002961 cvtArrayLength(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07002962 break;
2963 case greenland::IntrinsicHelper::NewArray:
2964 cvtNewArray(cUnit, callInst);
2965 break;
2966 case greenland::IntrinsicHelper::InstanceOf:
2967 cvtInstanceOf(cUnit, callInst);
2968 break;
2969
2970 case greenland::IntrinsicHelper::HLArrayGet:
2971 case greenland::IntrinsicHelper::HLArrayGetObject:
2972 case greenland::IntrinsicHelper::HLArrayGetFloat:
2973 cvtAget(cUnit, callInst, kWord, 2);
2974 break;
2975 case greenland::IntrinsicHelper::HLArrayGetWide:
2976 case greenland::IntrinsicHelper::HLArrayGetDouble:
2977 cvtAget(cUnit, callInst, kLong, 3);
2978 break;
2979 case greenland::IntrinsicHelper::HLArrayGetBoolean:
2980 cvtAget(cUnit, callInst, kUnsignedByte, 0);
2981 break;
2982 case greenland::IntrinsicHelper::HLArrayGetByte:
2983 cvtAget(cUnit, callInst, kSignedByte, 0);
2984 break;
2985 case greenland::IntrinsicHelper::HLArrayGetChar:
2986 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
2987 break;
2988 case greenland::IntrinsicHelper::HLArrayGetShort:
2989 cvtAget(cUnit, callInst, kSignedHalf, 1);
2990 break;
2991
2992 case greenland::IntrinsicHelper::HLArrayPut:
buzbee8fa0fda2012-06-27 15:44:52 -07002993 case greenland::IntrinsicHelper::HLArrayPutFloat:
buzbeef1f86362012-07-10 15:18:31 -07002994 cvtAputPrimitive(cUnit, callInst, kWord, 2);
2995 break;
2996 case greenland::IntrinsicHelper::HLArrayPutObject:
2997 cvtAputObj(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07002998 break;
2999 case greenland::IntrinsicHelper::HLArrayPutWide:
3000 case greenland::IntrinsicHelper::HLArrayPutDouble:
buzbeef1f86362012-07-10 15:18:31 -07003001 cvtAputPrimitive(cUnit, callInst, kLong, 3);
buzbee8fa0fda2012-06-27 15:44:52 -07003002 break;
3003 case greenland::IntrinsicHelper::HLArrayPutBoolean:
buzbeef1f86362012-07-10 15:18:31 -07003004 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
buzbee8fa0fda2012-06-27 15:44:52 -07003005 break;
3006 case greenland::IntrinsicHelper::HLArrayPutByte:
buzbeef1f86362012-07-10 15:18:31 -07003007 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
buzbee8fa0fda2012-06-27 15:44:52 -07003008 break;
3009 case greenland::IntrinsicHelper::HLArrayPutChar:
buzbeef1f86362012-07-10 15:18:31 -07003010 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
buzbee8fa0fda2012-06-27 15:44:52 -07003011 break;
3012 case greenland::IntrinsicHelper::HLArrayPutShort:
buzbeef1f86362012-07-10 15:18:31 -07003013 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
buzbee8fa0fda2012-06-27 15:44:52 -07003014 break;
3015
buzbee101305f2012-06-28 18:00:56 -07003016 case greenland::IntrinsicHelper::HLIGet:
3017 case greenland::IntrinsicHelper::HLIGetFloat:
3018 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3019 break;
3020 case greenland::IntrinsicHelper::HLIGetObject:
3021 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3022 break;
3023 case greenland::IntrinsicHelper::HLIGetWide:
3024 case greenland::IntrinsicHelper::HLIGetDouble:
3025 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3026 break;
3027 case greenland::IntrinsicHelper::HLIGetBoolean:
3028 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3029 false /* obj */);
3030 break;
3031 case greenland::IntrinsicHelper::HLIGetByte:
3032 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3033 false /* obj */);
3034 break;
3035 case greenland::IntrinsicHelper::HLIGetChar:
3036 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3037 false /* obj */);
3038 break;
3039 case greenland::IntrinsicHelper::HLIGetShort:
3040 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3041 false /* obj */);
3042 break;
3043
3044 case greenland::IntrinsicHelper::HLIPut:
3045 case greenland::IntrinsicHelper::HLIPutFloat:
3046 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3047 break;
3048 case greenland::IntrinsicHelper::HLIPutObject:
3049 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3050 break;
3051 case greenland::IntrinsicHelper::HLIPutWide:
3052 case greenland::IntrinsicHelper::HLIPutDouble:
3053 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3054 break;
3055 case greenland::IntrinsicHelper::HLIPutBoolean:
3056 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3057 false /* obj */);
3058 break;
3059 case greenland::IntrinsicHelper::HLIPutByte:
3060 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3061 false /* obj */);
3062 break;
3063 case greenland::IntrinsicHelper::HLIPutChar:
3064 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3065 false /* obj */);
3066 break;
3067 case greenland::IntrinsicHelper::HLIPutShort:
3068 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3069 false /* obj */);
3070 break;
3071
3072 case greenland::IntrinsicHelper::IntToChar:
3073 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3074 break;
3075 case greenland::IntrinsicHelper::IntToShort:
3076 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3077 break;
3078 case greenland::IntrinsicHelper::IntToByte:
3079 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3080 break;
3081
buzbee76592632012-06-29 15:18:35 -07003082 case greenland::IntrinsicHelper::CmplFloat:
3083 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3084 break;
3085 case greenland::IntrinsicHelper::CmpgFloat:
3086 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3087 break;
3088 case greenland::IntrinsicHelper::CmplDouble:
3089 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3090 break;
3091 case greenland::IntrinsicHelper::CmpgDouble:
3092 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3093 break;
3094
3095 case greenland::IntrinsicHelper::CmpLong:
3096 cvtLongCompare(cUnit, callInst);
3097 break;
3098
buzbee2a83e8f2012-07-13 16:42:30 -07003099 case greenland::IntrinsicHelper::SHLLong:
3100 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
buzbee2cfc6392012-05-07 14:51:40 -07003101 break;
buzbee2a83e8f2012-07-13 16:42:30 -07003102 case greenland::IntrinsicHelper::SHRLong:
3103 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3104 break;
3105 case greenland::IntrinsicHelper::USHRLong:
3106 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3107 break;
3108 case greenland::IntrinsicHelper::SHLInt:
3109 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3110 break;
3111 case greenland::IntrinsicHelper::SHRInt:
3112 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3113 break;
3114 case greenland::IntrinsicHelper::USHRInt:
3115 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3116 break;
3117
buzbee2cfc6392012-05-07 14:51:40 -07003118 default:
3119 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3120 << cUnit->intrinsic_helper->GetName(id);
3121 }
3122 }
3123 break;
3124
3125 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3126 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3127 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3128 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3129 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3130 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3131 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3132 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3133 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003134 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3135 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
buzbee4f1181f2012-06-22 13:52:12 -07003136 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3137 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3138 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3139 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3140 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
buzbee76592632012-06-29 15:18:35 -07003141 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
3142 case llvm::Instruction::FPToSI: cvtFPToInt(cUnit, inst); break;
3143 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3144 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3145 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003146
buzbee101305f2012-06-28 18:00:56 -07003147 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3148 break;
3149 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3150 break;
3151
buzbeef58c12c2012-07-03 15:06:29 -07003152 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3153
buzbee32412962012-06-26 16:27:56 -07003154 case llvm::Instruction::Unreachable:
3155 break; // FIXME: can we really ignore these?
3156
buzbee2a83e8f2012-07-13 16:42:30 -07003157 case llvm::Instruction::Shl:
3158 case llvm::Instruction::LShr:
3159 case llvm::Instruction::AShr:
buzbee2cfc6392012-05-07 14:51:40 -07003160 case llvm::Instruction::Invoke:
buzbee2cfc6392012-05-07 14:51:40 -07003161 case llvm::Instruction::FPToUI:
buzbee2cfc6392012-05-07 14:51:40 -07003162 case llvm::Instruction::UIToFP:
buzbee2cfc6392012-05-07 14:51:40 -07003163 case llvm::Instruction::PtrToInt:
3164 case llvm::Instruction::IntToPtr:
buzbee2cfc6392012-05-07 14:51:40 -07003165 case llvm::Instruction::FCmp:
buzbee2cfc6392012-05-07 14:51:40 -07003166 case llvm::Instruction::URem:
3167 case llvm::Instruction::UDiv:
3168 case llvm::Instruction::Resume:
buzbee2cfc6392012-05-07 14:51:40 -07003169 case llvm::Instruction::Alloca:
3170 case llvm::Instruction::GetElementPtr:
3171 case llvm::Instruction::Fence:
3172 case llvm::Instruction::AtomicCmpXchg:
3173 case llvm::Instruction::AtomicRMW:
3174 case llvm::Instruction::BitCast:
3175 case llvm::Instruction::VAArg:
3176 case llvm::Instruction::Select:
3177 case llvm::Instruction::UserOp1:
3178 case llvm::Instruction::UserOp2:
3179 case llvm::Instruction::ExtractElement:
3180 case llvm::Instruction::InsertElement:
3181 case llvm::Instruction::ShuffleVector:
3182 case llvm::Instruction::ExtractValue:
3183 case llvm::Instruction::InsertValue:
3184 case llvm::Instruction::LandingPad:
3185 case llvm::Instruction::IndirectBr:
3186 case llvm::Instruction::Load:
3187 case llvm::Instruction::Store:
3188 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3189
3190 default:
buzbee2a83e8f2012-07-13 16:42:30 -07003191 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3192 break;
buzbee2cfc6392012-05-07 14:51:40 -07003193 }
3194 }
buzbee6969d502012-06-15 16:40:31 -07003195
3196 if (headLIR != NULL) {
3197 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
3198 }
buzbee2cfc6392012-05-07 14:51:40 -07003199 return false;
3200}
3201
3202/*
3203 * Convert LLVM_IR to MIR:
3204 * o Iterate through the LLVM_IR and construct a graph using
3205 * standard MIR building blocks.
3206 * o Perform a basic-block optimization pass to remove unnecessary
3207 * store/load sequences.
3208 * o Convert the LLVM Value operands into RegLocations where applicable.
3209 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3210 * o Perform register promotion
3211 * o Iterate through the graph a basic block at a time, generating
3212 * LIR.
3213 * o Assemble LIR as usual.
3214 * o Profit.
3215 */
3216void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3217{
buzbeead8f15e2012-06-18 14:49:45 -07003218 llvm::Function* func = cUnit->func;
3219 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003220 // Allocate a list for LIR basic block labels
3221 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07003222 (LIR*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3223 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003224 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003225 for (llvm::Function::iterator i = func->begin(),
3226 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003227 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3228 &labelList[nextLabel++]);
3229 }
buzbeead8f15e2012-06-18 14:49:45 -07003230
3231 /*
3232 * Keep honest - clear regLocations, Value => RegLocation,
3233 * promotion map and VmapTables.
3234 */
3235 cUnit->locMap.clear(); // Start fresh
3236 cUnit->regLocation = NULL;
3237 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3238 i++) {
3239 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3240 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3241 }
3242 cUnit->coreSpillMask = 0;
3243 cUnit->numCoreSpills = 0;
3244 cUnit->fpSpillMask = 0;
3245 cUnit->numFPSpills = 0;
3246 cUnit->coreVmapTable.clear();
3247 cUnit->fpVmapTable.clear();
3248 oatAdjustSpillMask(cUnit);
3249 cUnit->frameSize = oatComputeFrameSize(cUnit);
3250
3251 /*
3252 * At this point, we've lost all knowledge of register promotion.
3253 * Rebuild that info from the MethodInfo intrinsic (if it
3254 * exists - not required for correctness).
3255 */
3256 // TODO: find and recover MethodInfo.
3257
3258 // Create RegLocations for arguments
3259 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3260 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3261 for (; it != it_end; ++it) {
3262 llvm::Value* val = it;
3263 createLocFromValue(cUnit, val);
3264 }
3265 // Create RegLocations for all non-argument defintions
3266 for (llvm::inst_iterator i = llvm::inst_begin(func),
3267 e = llvm::inst_end(func); i != e; ++i) {
3268 llvm::Value* val = &*i;
3269 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3270 createLocFromValue(cUnit, val);
3271 }
3272 }
3273
buzbee2cfc6392012-05-07 14:51:40 -07003274 // Walk the blocks, generating code.
3275 for (llvm::Function::iterator i = cUnit->func->begin(),
3276 e = cUnit->func->end(); i != e; ++i) {
3277 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3278 }
3279
3280 handleSuspendLaunchpads(cUnit);
3281
3282 handleThrowLaunchpads(cUnit);
3283
3284 handleIntrinsicLaunchpads(cUnit);
3285
3286 freeIR(cUnit);
3287}
3288
3289
3290} // namespace art
3291
3292#endif // ART_USE_QUICK_COMPILER