blob: e7e4e5a190ebc572263f4a9cc9701c6daa837f50 [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);
buzbee9a2487f2012-07-26 14:01:13 -070052 if (placeholder == NULL) {
53 // This can happen on instruction rewrite on verification failure
Bill Buzbeec9f40dd2012-08-15 11:35:25 -070054 LOG(WARNING) << "Null placeholder";
buzbee9a2487f2012-07-26 14:01:13 -070055 return;
56 }
buzbee2cfc6392012-05-07 14:51:40 -070057 placeholder->replaceAllUsesWith(val);
58 val->takeName(placeholder);
59 cUnit->llvmValues.elemList[sReg] = (intptr_t)val;
buzbee4be777b2012-07-12 14:38:18 -070060 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
61 DCHECK(inst != NULL);
62 inst->eraseFromParent();
buzbee2cfc6392012-05-07 14:51:40 -070063}
64
65llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
66{
67 llvm::Type* res = NULL;
68 if (loc.wide) {
69 if (loc.fp)
buzbee4f1181f2012-06-22 13:52:12 -070070 res = cUnit->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070071 else
buzbee4f1181f2012-06-22 13:52:12 -070072 res = cUnit->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070073 } else {
74 if (loc.fp) {
buzbee4f1181f2012-06-22 13:52:12 -070075 res = cUnit->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070076 } else {
77 if (loc.ref)
78 res = cUnit->irb->GetJObjectTy();
79 else
buzbee4f1181f2012-06-22 13:52:12 -070080 res = cUnit->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -070081 }
82 }
83 return res;
84}
85
buzbeead8f15e2012-06-18 14:49:45 -070086/* Create an in-memory RegLocation from an llvm Value. */
87void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
88{
89 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
90 std::string s(val->getName().str());
91 const char* valName = s.c_str();
buzbeead8f15e2012-06-18 14:49:45 -070092 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
93 DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
94 int baseSReg = INVALID_SREG;
95 int subscript = -1;
96 sscanf(valName, "v%d_%d", &baseSReg, &subscript);
97 if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
98 baseSReg = SSA_METHOD_BASEREG;
99 subscript = 0;
100 }
buzbeead8f15e2012-06-18 14:49:45 -0700101 DCHECK_NE(baseSReg, INVALID_SREG);
102 DCHECK_NE(subscript, -1);
103 // TODO: redo during C++'ification
104 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
105 INVALID_REG, INVALID_SREG, INVALID_SREG};
106 llvm::Type* ty = val->getType();
107 loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
108 (ty == cUnit->irb->getDoubleTy()));
109 loc.defined = true;
110 if ((ty == cUnit->irb->getFloatTy()) ||
111 (ty == cUnit->irb->getDoubleTy())) {
112 loc.fp = true;
113 } else if (ty == cUnit->irb->GetJObjectTy()) {
114 loc.ref = true;
115 } else {
116 loc.core = true;
117 }
118 loc.home = false; // Will change during promotion
119 loc.sRegLow = baseSReg;
120 loc.origSReg = cUnit->locMap.size();
121 cUnit->locMap.Put(val, loc);
122}
123
buzbee2cfc6392012-05-07 14:51:40 -0700124void initIR(CompilationUnit* cUnit)
125{
126 cUnit->context = new llvm::LLVMContext();
127 cUnit->module = new llvm::Module("art", *cUnit->context);
128 llvm::StructType::create(*cUnit->context, "JavaObject");
129 llvm::StructType::create(*cUnit->context, "Method");
130 llvm::StructType::create(*cUnit->context, "Thread");
131 cUnit->intrinsic_helper =
132 new greenland::IntrinsicHelper(*cUnit->context, *cUnit->module);
133 cUnit->irb =
134 new greenland::IRBuilder(*cUnit->context, *cUnit->module,
135 *cUnit->intrinsic_helper);
136}
137
138void freeIR(CompilationUnit* cUnit)
139{
140 delete cUnit->irb;
141 delete cUnit->intrinsic_helper;
142 delete cUnit->module;
143 delete cUnit->context;
144}
145
146const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
147 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
148}
149
buzbeef58c12c2012-07-03 15:06:29 -0700150llvm::BasicBlock* findCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
151{
152 BasicBlock* bb = oatFindBlock(cUnit, vaddr);
153 DCHECK(bb != NULL);
154 return getLLVMBlock(cUnit, bb->id);
155}
156
157void convertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
158 int32_t tableOffset, RegLocation rlSrc)
159{
160 const Instruction::PackedSwitchPayload* payload =
161 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
162 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
163
164 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
165
166 llvm::SwitchInst* sw =
167 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
168 payload->case_count);
169
170 for (uint16_t i = 0; i < payload->case_count; ++i) {
171 llvm::BasicBlock* llvmBB =
172 findCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
173 sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
174 }
175 llvm::MDNode* switchNode =
176 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
177 sw->setMetadata("SwitchTable", switchNode);
178 bb->taken = NULL;
179 bb->fallThrough = NULL;
180}
181
buzbeea1da8a52012-07-09 14:00:21 -0700182void convertSparseSwitch(CompilationUnit* cUnit, BasicBlock* bb,
183 int32_t tableOffset, RegLocation rlSrc)
184{
185 const Instruction::SparseSwitchPayload* payload =
186 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
187 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
188
189 const int32_t* keys = payload->GetKeys();
190 const int32_t* targets = payload->GetTargets();
191
192 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
193
194 llvm::SwitchInst* sw =
195 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
196 payload->case_count);
197
198 for (size_t i = 0; i < payload->case_count; ++i) {
199 llvm::BasicBlock* llvmBB =
200 findCaseTarget(cUnit, cUnit->currentDalvikOffset + targets[i]);
201 sw->addCase(cUnit->irb->getInt32(keys[i]), llvmBB);
202 }
203 llvm::MDNode* switchNode =
204 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
205 sw->setMetadata("SwitchTable", switchNode);
206 bb->taken = NULL;
207 bb->fallThrough = NULL;
208}
209
buzbee8fa0fda2012-06-27 15:44:52 -0700210void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
211 greenland::IntrinsicHelper::IntrinsicId id,
212 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700213{
buzbee8fa0fda2012-06-27 15:44:52 -0700214 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700215 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700216 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
217 defineValue(cUnit, res, rlDest.origSReg);
218}
219
220void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
221 greenland::IntrinsicHelper::IntrinsicId id,
222 RegLocation rlSrc)
223{
224 llvm::SmallVector<llvm::Value*, 2> args;
225 args.push_back(cUnit->irb->getInt32(fieldIndex));
226 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
227 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
228 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700229}
230
buzbee101305f2012-06-28 18:00:56 -0700231void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
232 RegLocation rlArray)
233{
234 greenland::IntrinsicHelper::IntrinsicId id;
235 id = greenland::IntrinsicHelper::FillArrayData;
236 llvm::SmallVector<llvm::Value*, 2> args;
237 args.push_back(cUnit->irb->getInt32(offset));
238 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
239 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
240 cUnit->irb->CreateCall(intr, args);
241}
242
buzbee2cfc6392012-05-07 14:51:40 -0700243llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
244 RegLocation loc)
245{
246 greenland::IntrinsicHelper::IntrinsicId id;
247 if (loc.wide) {
248 if (loc.fp) {
249 id = greenland::IntrinsicHelper::ConstDouble;
250 } else {
251 id = greenland::IntrinsicHelper::ConstLong;
252 }
253 } else {
254 if (loc.fp) {
255 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700256 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700257 id = greenland::IntrinsicHelper::ConstObj;
258 } else {
259 id = greenland::IntrinsicHelper::ConstInt;
260 }
261 }
262 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
263 return cUnit->irb->CreateCall(intr, src);
264}
buzbeeb03f4872012-06-11 15:22:11 -0700265
266void emitPopShadowFrame(CompilationUnit* cUnit)
267{
268 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
269 greenland::IntrinsicHelper::PopShadowFrame);
270 cUnit->irb->CreateCall(intr);
271}
272
buzbee2cfc6392012-05-07 14:51:40 -0700273llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
274 RegLocation loc)
275{
276 greenland::IntrinsicHelper::IntrinsicId id;
277 if (loc.wide) {
278 if (loc.fp) {
279 id = greenland::IntrinsicHelper::CopyDouble;
280 } else {
281 id = greenland::IntrinsicHelper::CopyLong;
282 }
283 } else {
284 if (loc.fp) {
285 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700286 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700287 id = greenland::IntrinsicHelper::CopyObj;
288 } else {
289 id = greenland::IntrinsicHelper::CopyInt;
290 }
291 }
292 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
293 return cUnit->irb->CreateCall(intr, src);
294}
295
buzbee32412962012-06-26 16:27:56 -0700296void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
297{
298 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
299 greenland::IntrinsicHelper::GetException);
300 llvm::Value* res = cUnit->irb->CreateCall(func);
301 defineValue(cUnit, res, rlDest.origSReg);
302}
303
304void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
305{
306 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
307 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
308 greenland::IntrinsicHelper::Throw);
309 cUnit->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700310}
311
buzbee8fa0fda2012-06-27 15:44:52 -0700312void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
313 greenland::IntrinsicHelper::IntrinsicId id,
314 RegLocation rlSrc)
315{
316 llvm::SmallVector<llvm::Value*, 2> args;
317 args.push_back(cUnit->irb->getInt32(optFlags));
318 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
319 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
320 cUnit->irb->CreateCall(func, args);
321}
322
buzbee76592632012-06-29 15:18:35 -0700323void convertArrayLength(CompilationUnit* cUnit, int optFlags,
324 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700325{
326 llvm::SmallVector<llvm::Value*, 2> args;
327 args.push_back(cUnit->irb->getInt32(optFlags));
328 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
329 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
330 greenland::IntrinsicHelper::ArrayLength);
buzbee76592632012-06-29 15:18:35 -0700331 llvm::Value* res = cUnit->irb->CreateCall(func, args);
332 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700333}
334
buzbee32412962012-06-26 16:27:56 -0700335void convertThrowVerificationError(CompilationUnit* cUnit, int info1, int info2)
336{
337 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
buzbeea1da8a52012-07-09 14:00:21 -0700338 greenland::IntrinsicHelper::ThrowVerificationError);
buzbee32412962012-06-26 16:27:56 -0700339 llvm::SmallVector<llvm::Value*, 2> args;
340 args.push_back(cUnit->irb->getInt32(info1));
341 args.push_back(cUnit->irb->getInt32(info2));
342 cUnit->irb->CreateCall(func, args);
buzbee32412962012-06-26 16:27:56 -0700343}
344
buzbee2cfc6392012-05-07 14:51:40 -0700345void emitSuspendCheck(CompilationUnit* cUnit)
346{
347 greenland::IntrinsicHelper::IntrinsicId id =
348 greenland::IntrinsicHelper::CheckSuspend;
349 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
350 cUnit->irb->CreateCall(intr);
351}
352
353llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
354 llvm::Value* src1, llvm::Value* src2)
355{
356 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700357 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700358 switch(cc) {
359 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
360 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
361 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
362 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
363 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
364 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
365 default: LOG(FATAL) << "Unexpected cc value " << cc;
366 }
367 return res;
368}
369
370void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
371 ConditionCode cc, RegLocation rlSrc1,
372 RegLocation rlSrc2)
373{
374 if (bb->taken->startOffset <= mir->offset) {
375 emitSuspendCheck(cUnit);
376 }
377 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
378 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
379 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
380 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
381 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
382 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700383 // Don't redo the fallthrough branch in the BB driver
384 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700385}
386
387void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
388 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
389{
390 if (bb->taken->startOffset <= mir->offset) {
391 emitSuspendCheck(cUnit);
392 }
393 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
394 llvm::Value* src2;
395 if (rlSrc1.ref) {
396 src2 = cUnit->irb->GetJNull();
397 } else {
398 src2 = cUnit->irb->getInt32(0);
399 }
400 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700401 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
402 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700403 // Don't redo the fallthrough branch in the BB driver
404 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700405}
406
407llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
408 llvm::Value* src1, llvm::Value* src2)
409{
410 greenland::IntrinsicHelper::IntrinsicId id;
411 if (isLong) {
412 if (isDiv) {
413 id = greenland::IntrinsicHelper::DivLong;
414 } else {
415 id = greenland::IntrinsicHelper::RemLong;
416 }
417 } else if (isDiv) {
418 id = greenland::IntrinsicHelper::DivInt;
419 } else {
420 id = greenland::IntrinsicHelper::RemInt;
421 }
422 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
423 llvm::SmallVector<llvm::Value*, 2>args;
424 args.push_back(src1);
425 args.push_back(src2);
426 return cUnit->irb->CreateCall(intr, args);
427}
428
429llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
430 llvm::Value* src1, llvm::Value* src2)
431{
432 llvm::Value* res = NULL;
433 switch(op) {
434 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
435 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700436 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700437 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
438 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
439 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
440 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
441 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
442 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700443 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
444 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
445 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700446 default:
447 LOG(FATAL) << "Invalid op " << op;
448 }
449 return res;
450}
451
452void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
453 RegLocation rlSrc1, RegLocation rlSrc2)
454{
455 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
456 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
457 llvm::Value* res = NULL;
458 switch(op) {
459 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
460 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
461 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
462 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
463 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
464 default:
465 LOG(FATAL) << "Invalid op " << op;
466 }
467 defineValue(cUnit, res, rlDest.origSReg);
468}
469
buzbee2a83e8f2012-07-13 16:42:30 -0700470void convertShift(CompilationUnit* cUnit,
471 greenland::IntrinsicHelper::IntrinsicId id,
472 RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
buzbee4f1181f2012-06-22 13:52:12 -0700473{
buzbee2a83e8f2012-07-13 16:42:30 -0700474 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
475 llvm::SmallVector<llvm::Value*, 2>args;
476 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
477 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
478 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
479 defineValue(cUnit, res, rlDest.origSReg);
480}
481
482void convertShiftLit(CompilationUnit* cUnit,
483 greenland::IntrinsicHelper::IntrinsicId id,
484 RegLocation rlDest, RegLocation rlSrc, int shiftAmount)
485{
486 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
487 llvm::SmallVector<llvm::Value*, 2>args;
488 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
489 args.push_back(cUnit->irb->getInt32(shiftAmount));
490 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700491 defineValue(cUnit, res, rlDest.origSReg);
492}
493
buzbee2cfc6392012-05-07 14:51:40 -0700494void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
495 RegLocation rlSrc1, RegLocation rlSrc2)
496{
497 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
498 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700499 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700500 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
501 defineValue(cUnit, res, rlDest.origSReg);
502}
503
buzbeeb03f4872012-06-11 15:22:11 -0700504void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
505{
506 int index = -1;
507 DCHECK(newVal != NULL);
508 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
509 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
510 if (cUnit->shadowMap[i] == vReg) {
511 index = i;
512 break;
513 }
514 }
Elliott Hughes74847412012-06-20 18:10:21 -0700515 DCHECK_NE(index, -1) << "Corrupt shadowMap";
buzbeeb03f4872012-06-11 15:22:11 -0700516 greenland::IntrinsicHelper::IntrinsicId id =
517 greenland::IntrinsicHelper::SetShadowFrameEntry;
518 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
519 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
520 llvm::Value* args[] = { newVal, tableSlot };
521 cUnit->irb->CreateCall(func, args);
522}
523
buzbee2cfc6392012-05-07 14:51:40 -0700524void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
525 RegLocation rlSrc1, int32_t imm)
526{
527 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
528 llvm::Value* src2 = cUnit->irb->getInt32(imm);
529 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
530 defineValue(cUnit, res, rlDest.origSReg);
531}
532
buzbee101305f2012-06-28 18:00:56 -0700533/*
534 * Process arguments for invoke. Note: this code is also used to
535 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
536 * The requirements are similar.
537 */
buzbee6969d502012-06-15 16:40:31 -0700538void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700539 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700540{
541 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
542 llvm::SmallVector<llvm::Value*, 10> args;
543 // Insert the invokeType
544 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
545 // Insert the method_idx
546 args.push_back(cUnit->irb->getInt32(info->index));
547 // Insert the optimization flags
548 args.push_back(cUnit->irb->getInt32(info->optFlags));
549 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700550 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700551 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
552 args.push_back(val);
553 i += info->args[i].wide ? 2 : 1;
554 }
555 /*
556 * Choose the invoke return type based on actual usage. Note: may
557 * be different than shorty. For example, if a function return value
558 * is not used, we'll treat this as a void invoke.
559 */
560 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700561 if (isFilledNewArray) {
562 id = greenland::IntrinsicHelper::FilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700563 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700564 id = greenland::IntrinsicHelper::HLInvokeVoid;
565 } else {
566 if (info->result.wide) {
567 if (info->result.fp) {
568 id = greenland::IntrinsicHelper::HLInvokeDouble;
569 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700570 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700571 }
572 } else if (info->result.ref) {
573 id = greenland::IntrinsicHelper::HLInvokeObj;
574 } else if (info->result.fp) {
575 id = greenland::IntrinsicHelper::HLInvokeFloat;
576 } else {
577 id = greenland::IntrinsicHelper::HLInvokeInt;
578 }
579 }
580 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
581 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
582 if (info->result.location != kLocInvalid) {
583 defineValue(cUnit, res, info->result.origSReg);
584 }
585}
586
buzbee101305f2012-06-28 18:00:56 -0700587void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
588 greenland::IntrinsicHelper::IntrinsicId id,
589 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700590{
buzbee6969d502012-06-15 16:40:31 -0700591 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700592 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700593 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
594 defineValue(cUnit, res, rlDest.origSReg);
595}
596
buzbee101305f2012-06-28 18:00:56 -0700597void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
598 RegLocation rlSrc)
599{
600 greenland::IntrinsicHelper::IntrinsicId id;
601 id = greenland::IntrinsicHelper::CheckCast;
602 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
603 llvm::SmallVector<llvm::Value*, 2> args;
604 args.push_back(cUnit->irb->getInt32(type_idx));
605 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
606 cUnit->irb->CreateCall(intr, args);
607}
608
buzbee8fa0fda2012-06-27 15:44:52 -0700609void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
610 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700611{
612 greenland::IntrinsicHelper::IntrinsicId id;
613 id = greenland::IntrinsicHelper::NewInstance;
614 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
615 llvm::Value* index = cUnit->irb->getInt32(type_idx);
616 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
617 defineValue(cUnit, res, rlDest.origSReg);
618}
619
buzbee8fa0fda2012-06-27 15:44:52 -0700620void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
621 RegLocation rlDest, RegLocation rlSrc)
622{
623 greenland::IntrinsicHelper::IntrinsicId id;
624 id = greenland::IntrinsicHelper::NewArray;
625 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
626 llvm::SmallVector<llvm::Value*, 2> args;
627 args.push_back(cUnit->irb->getInt32(type_idx));
628 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
629 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
630 defineValue(cUnit, res, rlDest.origSReg);
631}
632
633void convertAget(CompilationUnit* cUnit, int optFlags,
634 greenland::IntrinsicHelper::IntrinsicId id,
635 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
636{
637 llvm::SmallVector<llvm::Value*, 3> args;
638 args.push_back(cUnit->irb->getInt32(optFlags));
639 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
640 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
641 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
642 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
643 defineValue(cUnit, res, rlDest.origSReg);
644}
645
646void convertAput(CompilationUnit* cUnit, int optFlags,
647 greenland::IntrinsicHelper::IntrinsicId id,
648 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
649{
650 llvm::SmallVector<llvm::Value*, 4> args;
651 args.push_back(cUnit->irb->getInt32(optFlags));
652 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
653 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
654 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
655 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
656 cUnit->irb->CreateCall(intr, args);
657}
658
buzbee101305f2012-06-28 18:00:56 -0700659void convertIget(CompilationUnit* cUnit, int optFlags,
660 greenland::IntrinsicHelper::IntrinsicId id,
661 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
662{
663 llvm::SmallVector<llvm::Value*, 3> args;
664 args.push_back(cUnit->irb->getInt32(optFlags));
665 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
666 args.push_back(cUnit->irb->getInt32(fieldIndex));
667 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
668 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
669 defineValue(cUnit, res, rlDest.origSReg);
670}
671
672void convertIput(CompilationUnit* cUnit, int optFlags,
673 greenland::IntrinsicHelper::IntrinsicId id,
674 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
675{
676 llvm::SmallVector<llvm::Value*, 4> args;
677 args.push_back(cUnit->irb->getInt32(optFlags));
678 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
679 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
680 args.push_back(cUnit->irb->getInt32(fieldIndex));
681 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
682 cUnit->irb->CreateCall(intr, args);
683}
684
buzbee8fa0fda2012-06-27 15:44:52 -0700685void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
686 RegLocation rlDest, RegLocation rlSrc)
687{
688 greenland::IntrinsicHelper::IntrinsicId id;
689 id = greenland::IntrinsicHelper::InstanceOf;
690 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
691 llvm::SmallVector<llvm::Value*, 2> args;
692 args.push_back(cUnit->irb->getInt32(type_idx));
693 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
694 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
695 defineValue(cUnit, res, rlDest.origSReg);
696}
697
buzbee101305f2012-06-28 18:00:56 -0700698void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
699 RegLocation rlSrc)
700{
701 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
702 cUnit->irb->getInt64Ty());
703 defineValue(cUnit, res, rlDest.origSReg);
704}
705
buzbee76592632012-06-29 15:18:35 -0700706void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
707 RegLocation rlSrc)
708{
709 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
710 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
711 defineValue(cUnit, res, rlDest.origSReg);
712}
713
714void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
715 RegLocation rlSrc)
716{
717 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
718 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
719 defineValue(cUnit, res, rlDest.origSReg);
720}
721
722void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
723 RegLocation rlSrc)
724{
725 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
726 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
727 defineValue(cUnit, res, rlDest.origSReg);
728}
729
730void convertWideComparison(CompilationUnit* cUnit,
731 greenland::IntrinsicHelper::IntrinsicId id,
732 RegLocation rlDest, RegLocation rlSrc1,
733 RegLocation rlSrc2)
734{
735 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
736 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
737 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
738 llvm::SmallVector<llvm::Value*, 2> args;
739 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
740 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
741 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
742 defineValue(cUnit, res, rlDest.origSReg);
743}
744
buzbee101305f2012-06-28 18:00:56 -0700745void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
746 RegLocation rlSrc,
747 greenland::IntrinsicHelper::IntrinsicId id)
748{
749 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700750 llvm::Value* res =
751 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
752 defineValue(cUnit, res, rlDest.origSReg);
753}
754
755void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
756 RegLocation rlSrc)
757{
758 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
759 defineValue(cUnit, res, rlDest.origSReg);
760}
761
762void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
763 RegLocation rlSrc)
764{
765 llvm::Value* res =
766 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
767 defineValue(cUnit, res, rlDest.origSReg);
768}
769
770void convertFPToInt(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
771 RegLocation rlSrc)
772{
773 llvm::Value* res =
774 cUnit->irb->CreateFPToSI(getLLVMValue(cUnit, rlSrc.origSReg), ty);
775 defineValue(cUnit, res, rlDest.origSReg);
776}
777
778
779void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
780 RegLocation rlSrc)
781{
782 llvm::Value* res =
783 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
784 defineValue(cUnit, res, rlDest.origSReg);
785}
786
787void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
788 RegLocation rlSrc)
789{
790 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
791 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700792 defineValue(cUnit, res, rlDest.origSReg);
793}
794
buzbee2cfc6392012-05-07 14:51:40 -0700795/*
796 * Target-independent code generation. Use only high-level
797 * load/store utilities here, or target-dependent genXX() handlers
798 * when necessary.
799 */
800bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
801 llvm::BasicBlock* llvmBB, LIR* labelList)
802{
803 bool res = false; // Assume success
804 RegLocation rlSrc[3];
805 RegLocation rlDest = badLoc;
buzbee2cfc6392012-05-07 14:51:40 -0700806 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee32412962012-06-26 16:27:56 -0700807 uint32_t vA = mir->dalvikInsn.vA;
buzbee6969d502012-06-15 16:40:31 -0700808 uint32_t vB = mir->dalvikInsn.vB;
809 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700810 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700811
buzbeeb03f4872012-06-11 15:22:11 -0700812 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700813
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700814 if (cUnit->printMe) {
815 if ((int)opcode < kMirOpFirst) {
816 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x"
817 << std::hex << (int)opcode;
818 } else {
819 LOG(INFO) << ".. opcode 0x" << std::hex << (int)opcode;
820 }
821 }
822
buzbee2cfc6392012-05-07 14:51:40 -0700823 /* Prep Src and Dest locations */
824 int nextSreg = 0;
825 int nextLoc = 0;
826 int attrs = oatDataFlowAttributes[opcode];
827 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
828 if (attrs & DF_UA) {
829 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700830 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700831 nextSreg+= 2;
832 } else {
833 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
834 nextSreg++;
835 }
836 }
837 if (attrs & DF_UB) {
838 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700839 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700840 nextSreg+= 2;
841 } else {
842 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
843 nextSreg++;
844 }
845 }
846 if (attrs & DF_UC) {
847 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700848 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700849 } else {
850 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
851 }
852 }
853 if (attrs & DF_DA) {
854 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700855 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700856 } else {
buzbee15bf9802012-06-12 17:49:27 -0700857 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700858 if (rlDest.ref) {
859 objectDefinition = true;
860 }
buzbee2cfc6392012-05-07 14:51:40 -0700861 }
862 }
863
864 switch (opcode) {
865 case Instruction::NOP:
866 break;
867
868 case Instruction::MOVE:
869 case Instruction::MOVE_OBJECT:
870 case Instruction::MOVE_16:
871 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700872 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700873 case Instruction::MOVE_FROM16:
874 case Instruction::MOVE_WIDE:
875 case Instruction::MOVE_WIDE_16:
876 case Instruction::MOVE_WIDE_FROM16: {
877 /*
878 * Moves/copies are meaningless in pure SSA register form,
879 * but we need to preserve them for the conversion back into
880 * MIR (at least until we stop using the Dalvik register maps).
881 * Insert a dummy intrinsic copy call, which will be recognized
882 * by the quick path and removed by the portable path.
883 */
884 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
885 llvm::Value* res = emitCopy(cUnit, src, rlDest);
886 defineValue(cUnit, res, rlDest.origSReg);
887 }
888 break;
889
890 case Instruction::CONST:
891 case Instruction::CONST_4:
892 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700893 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700894 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
895 defineValue(cUnit, res, rlDest.origSReg);
896 }
897 break;
898
899 case Instruction::CONST_WIDE_16:
900 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700901 // Sign extend to 64 bits
902 int64_t imm = static_cast<int32_t>(vB);
903 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700904 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
905 defineValue(cUnit, res, rlDest.origSReg);
906 }
907 break;
908
909 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700910 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700911 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
912 defineValue(cUnit, res, rlDest.origSReg);
913 }
914 break;
915
916 case Instruction::CONST_WIDE: {
917 llvm::Constant* immValue =
918 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
919 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
920 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700921 }
922 break;
buzbee2cfc6392012-05-07 14:51:40 -0700923 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700924 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700925 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
926 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
927 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700928 }
929 break;
930
buzbee8fa0fda2012-06-27 15:44:52 -0700931 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700932 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700933 rlSrc[0]);
934 break;
935 case Instruction::SPUT:
936 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700937 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700938 rlSrc[0]);
939 } else {
buzbee76592632012-06-29 15:18:35 -0700940 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700941 }
942 break;
943 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700944 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700945 rlSrc[0]);
946 break;
947 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700948 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700949 break;
950 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700951 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700952 break;
953 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -0700954 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700955 break;
956 case Instruction::SPUT_WIDE:
957 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700958 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -0700959 rlSrc[0]);
960 } else {
buzbee76592632012-06-29 15:18:35 -0700961 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -0700962 rlSrc[0]);
963 }
964 break;
965
966 case Instruction::SGET_OBJECT:
967 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
968 break;
969 case Instruction::SGET:
970 if (rlDest.fp) {
971 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
972 } else {
973 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
974 }
975 break;
976 case Instruction::SGET_BOOLEAN:
977 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
978 break;
979 case Instruction::SGET_BYTE:
980 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
981 break;
982 case Instruction::SGET_CHAR:
983 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
984 break;
985 case Instruction::SGET_SHORT:
986 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
987 break;
988 case Instruction::SGET_WIDE:
989 if (rlDest.fp) {
990 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
991 rlDest);
992 } else {
993 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -0700994 }
995 break;
buzbee2cfc6392012-05-07 14:51:40 -0700996
997 case Instruction::RETURN_WIDE:
998 case Instruction::RETURN:
999 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -07001000 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001001 emitSuspendCheck(cUnit);
1002 }
buzbeeb03f4872012-06-11 15:22:11 -07001003 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001004 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
1005 bb->hasReturn = true;
1006 }
1007 break;
1008
1009 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001010 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001011 emitSuspendCheck(cUnit);
1012 }
buzbeeb03f4872012-06-11 15:22:11 -07001013 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001014 cUnit->irb->CreateRetVoid();
1015 bb->hasReturn = true;
1016 }
1017 break;
1018
1019 case Instruction::IF_EQ:
1020 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1021 break;
1022 case Instruction::IF_NE:
1023 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1024 break;
1025 case Instruction::IF_LT:
1026 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1027 break;
1028 case Instruction::IF_GE:
1029 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1030 break;
1031 case Instruction::IF_GT:
1032 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1033 break;
1034 case Instruction::IF_LE:
1035 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1036 break;
1037 case Instruction::IF_EQZ:
1038 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1039 break;
1040 case Instruction::IF_NEZ:
1041 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1042 break;
1043 case Instruction::IF_LTZ:
1044 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1045 break;
1046 case Instruction::IF_GEZ:
1047 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1048 break;
1049 case Instruction::IF_GTZ:
1050 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1051 break;
1052 case Instruction::IF_LEZ:
1053 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1054 break;
1055
1056 case Instruction::GOTO:
1057 case Instruction::GOTO_16:
1058 case Instruction::GOTO_32: {
1059 if (bb->taken->startOffset <= bb->startOffset) {
1060 emitSuspendCheck(cUnit);
1061 }
1062 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1063 }
1064 break;
1065
1066 case Instruction::ADD_LONG:
1067 case Instruction::ADD_LONG_2ADDR:
1068 case Instruction::ADD_INT:
1069 case Instruction::ADD_INT_2ADDR:
1070 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1071 break;
1072 case Instruction::SUB_LONG:
1073 case Instruction::SUB_LONG_2ADDR:
1074 case Instruction::SUB_INT:
1075 case Instruction::SUB_INT_2ADDR:
1076 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1077 break;
1078 case Instruction::MUL_LONG:
1079 case Instruction::MUL_LONG_2ADDR:
1080 case Instruction::MUL_INT:
1081 case Instruction::MUL_INT_2ADDR:
1082 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1083 break;
1084 case Instruction::DIV_LONG:
1085 case Instruction::DIV_LONG_2ADDR:
1086 case Instruction::DIV_INT:
1087 case Instruction::DIV_INT_2ADDR:
1088 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1089 break;
1090 case Instruction::REM_LONG:
1091 case Instruction::REM_LONG_2ADDR:
1092 case Instruction::REM_INT:
1093 case Instruction::REM_INT_2ADDR:
1094 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1095 break;
1096 case Instruction::AND_LONG:
1097 case Instruction::AND_LONG_2ADDR:
1098 case Instruction::AND_INT:
1099 case Instruction::AND_INT_2ADDR:
1100 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1101 break;
1102 case Instruction::OR_LONG:
1103 case Instruction::OR_LONG_2ADDR:
1104 case Instruction::OR_INT:
1105 case Instruction::OR_INT_2ADDR:
1106 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1107 break;
1108 case Instruction::XOR_LONG:
1109 case Instruction::XOR_LONG_2ADDR:
1110 case Instruction::XOR_INT:
1111 case Instruction::XOR_INT_2ADDR:
1112 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1113 break;
1114 case Instruction::SHL_LONG:
1115 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001116 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1117 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001118 break;
buzbee2cfc6392012-05-07 14:51:40 -07001119 case Instruction::SHL_INT:
1120 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001121 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1122 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001123 break;
1124 case Instruction::SHR_LONG:
1125 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001126 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1127 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001128 break;
buzbee2cfc6392012-05-07 14:51:40 -07001129 case Instruction::SHR_INT:
1130 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001131 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1132 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001133 break;
1134 case Instruction::USHR_LONG:
1135 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001136 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1137 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001138 break;
buzbee2cfc6392012-05-07 14:51:40 -07001139 case Instruction::USHR_INT:
1140 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001141 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1142 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001143 break;
1144
1145 case Instruction::ADD_INT_LIT16:
1146 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001147 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001148 break;
1149 case Instruction::RSUB_INT:
1150 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001151 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001152 break;
1153 case Instruction::MUL_INT_LIT16:
1154 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001155 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001156 break;
1157 case Instruction::DIV_INT_LIT16:
1158 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001159 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001160 break;
1161 case Instruction::REM_INT_LIT16:
1162 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001163 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001164 break;
1165 case Instruction::AND_INT_LIT16:
1166 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001167 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001168 break;
1169 case Instruction::OR_INT_LIT16:
1170 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001171 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001172 break;
1173 case Instruction::XOR_INT_LIT16:
1174 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001175 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001176 break;
1177 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001178 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1179 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001180 break;
1181 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001182 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1183 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001184 break;
1185 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001186 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1187 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001188 break;
1189
1190 case Instruction::ADD_FLOAT:
1191 case Instruction::ADD_FLOAT_2ADDR:
1192 case Instruction::ADD_DOUBLE:
1193 case Instruction::ADD_DOUBLE_2ADDR:
1194 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1195 break;
1196
1197 case Instruction::SUB_FLOAT:
1198 case Instruction::SUB_FLOAT_2ADDR:
1199 case Instruction::SUB_DOUBLE:
1200 case Instruction::SUB_DOUBLE_2ADDR:
1201 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1202 break;
1203
1204 case Instruction::MUL_FLOAT:
1205 case Instruction::MUL_FLOAT_2ADDR:
1206 case Instruction::MUL_DOUBLE:
1207 case Instruction::MUL_DOUBLE_2ADDR:
1208 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1209 break;
1210
1211 case Instruction::DIV_FLOAT:
1212 case Instruction::DIV_FLOAT_2ADDR:
1213 case Instruction::DIV_DOUBLE:
1214 case Instruction::DIV_DOUBLE_2ADDR:
1215 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1216 break;
1217
1218 case Instruction::REM_FLOAT:
1219 case Instruction::REM_FLOAT_2ADDR:
1220 case Instruction::REM_DOUBLE:
1221 case Instruction::REM_DOUBLE_2ADDR:
1222 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1223 break;
1224
buzbee6969d502012-06-15 16:40:31 -07001225 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001226 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1227 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001228 break;
1229 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001230 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1231 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001232 break;
1233
1234 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001235 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1236 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001237 break;
1238 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001239 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1240 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001241 break;
1242
1243 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001244 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1245 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001246 break;
1247 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001248 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1249 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001250 break;
1251
1252 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001253 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1254 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001255 break;
1256 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001257 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1258 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001259 break;
1260
1261 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001262 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1263 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001264 break;
1265 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001266 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1267 false /* NewFilledArray */);
1268 break;
1269 case Instruction::FILLED_NEW_ARRAY:
1270 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1271 true /* NewFilledArray */);
1272 break;
1273 case Instruction::FILLED_NEW_ARRAY_RANGE:
1274 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1275 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001276 break;
1277
1278 case Instruction::CONST_STRING:
1279 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001280 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1281 rlDest);
1282 break;
1283
1284 case Instruction::CONST_CLASS:
1285 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1286 rlDest);
1287 break;
1288
1289 case Instruction::CHECK_CAST:
1290 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001291 break;
1292
buzbee4f1181f2012-06-22 13:52:12 -07001293 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001294 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001295 break;
1296
buzbee32412962012-06-26 16:27:56 -07001297 case Instruction::MOVE_EXCEPTION:
1298 convertMoveException(cUnit, rlDest);
1299 break;
1300
1301 case Instruction::THROW:
1302 convertThrow(cUnit, rlSrc[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001303 /*
1304 * If this throw is standalone, terminate.
1305 * If it might rethrow, force termination
1306 * of the following block.
1307 */
1308 if (bb->fallThrough == NULL) {
1309 cUnit->irb->CreateUnreachable();
1310 } else {
1311 bb->fallThrough->fallThrough = NULL;
1312 bb->fallThrough->taken = NULL;
1313 }
buzbee32412962012-06-26 16:27:56 -07001314 break;
1315
1316 case Instruction::THROW_VERIFICATION_ERROR:
1317 convertThrowVerificationError(cUnit, vA, vB);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001318 UNIMPLEMENTED(WARNING) << "Need dead code elimination pass"
1319 << " - disabling bitcode verification";
1320 cUnit->enableDebug &= ~(1 << kDebugVerifyBitcode);
buzbee32412962012-06-26 16:27:56 -07001321 break;
buzbee6969d502012-06-15 16:40:31 -07001322
buzbee2cfc6392012-05-07 14:51:40 -07001323 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001324 case Instruction::MOVE_RESULT:
1325 case Instruction::MOVE_RESULT_OBJECT:
buzbee85eee022012-07-16 22:12:38 -07001326#if defined(TARGET_ARM)
buzbee9a2487f2012-07-26 14:01:13 -07001327 /*
1328 * Instruction rewriting on verification failure can eliminate
1329 * the invoke that feeds this move0result. It won't ever be reached,
1330 * so we can ignore it.
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001331 * TODO: verify that previous instruction is THROW_VERIFICATION_ERROR,
1332 * or better, add dead-code elimination.
buzbee9a2487f2012-07-26 14:01:13 -07001333 */
1334 UNIMPLEMENTED(WARNING) << "Need to verify previous inst was rewritten";
buzbee85eee022012-07-16 22:12:38 -07001335#else
1336 UNIMPLEMENTED(WARNING) << "need x86 move-result fusing";
1337#endif
1338
buzbee2cfc6392012-05-07 14:51:40 -07001339 break;
1340
1341 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001342 convertMonitorEnterExit(cUnit, optFlags,
1343 greenland::IntrinsicHelper::MonitorEnter,
1344 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001345 break;
1346
1347 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001348 convertMonitorEnterExit(cUnit, optFlags,
1349 greenland::IntrinsicHelper::MonitorExit,
1350 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001351 break;
1352
1353 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001354 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001355 break;
1356
1357 case Instruction::NEW_ARRAY:
1358 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1359 break;
1360
1361 case Instruction::INSTANCE_OF:
1362 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1363 break;
1364
1365 case Instruction::AGET:
1366 if (rlDest.fp) {
1367 convertAget(cUnit, optFlags,
1368 greenland::IntrinsicHelper::HLArrayGetFloat,
1369 rlDest, rlSrc[0], rlSrc[1]);
1370 } else {
1371 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1372 rlDest, rlSrc[0], rlSrc[1]);
1373 }
1374 break;
1375 case Instruction::AGET_OBJECT:
1376 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1377 rlDest, rlSrc[0], rlSrc[1]);
1378 break;
1379 case Instruction::AGET_BOOLEAN:
1380 convertAget(cUnit, optFlags,
1381 greenland::IntrinsicHelper::HLArrayGetBoolean,
1382 rlDest, rlSrc[0], rlSrc[1]);
1383 break;
1384 case Instruction::AGET_BYTE:
1385 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1386 rlDest, rlSrc[0], rlSrc[1]);
1387 break;
1388 case Instruction::AGET_CHAR:
1389 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1390 rlDest, rlSrc[0], rlSrc[1]);
1391 break;
1392 case Instruction::AGET_SHORT:
1393 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1394 rlDest, rlSrc[0], rlSrc[1]);
1395 break;
1396 case Instruction::AGET_WIDE:
1397 if (rlDest.fp) {
1398 convertAget(cUnit, optFlags,
1399 greenland::IntrinsicHelper::HLArrayGetDouble,
1400 rlDest, rlSrc[0], rlSrc[1]);
1401 } else {
1402 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1403 rlDest, rlSrc[0], rlSrc[1]);
1404 }
1405 break;
1406
1407 case Instruction::APUT:
1408 if (rlSrc[0].fp) {
1409 convertAput(cUnit, optFlags,
1410 greenland::IntrinsicHelper::HLArrayPutFloat,
1411 rlSrc[0], rlSrc[1], rlSrc[2]);
1412 } else {
1413 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1414 rlSrc[0], rlSrc[1], rlSrc[2]);
1415 }
1416 break;
1417 case Instruction::APUT_OBJECT:
1418 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1419 rlSrc[0], rlSrc[1], rlSrc[2]);
1420 break;
1421 case Instruction::APUT_BOOLEAN:
1422 convertAput(cUnit, optFlags,
1423 greenland::IntrinsicHelper::HLArrayPutBoolean,
1424 rlSrc[0], rlSrc[1], rlSrc[2]);
1425 break;
1426 case Instruction::APUT_BYTE:
1427 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1428 rlSrc[0], rlSrc[1], rlSrc[2]);
1429 break;
1430 case Instruction::APUT_CHAR:
1431 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1432 rlSrc[0], rlSrc[1], rlSrc[2]);
1433 break;
1434 case Instruction::APUT_SHORT:
1435 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1436 rlSrc[0], rlSrc[1], rlSrc[2]);
1437 break;
1438 case Instruction::APUT_WIDE:
1439 if (rlSrc[0].fp) {
1440 convertAput(cUnit, optFlags,
1441 greenland::IntrinsicHelper::HLArrayPutDouble,
1442 rlSrc[0], rlSrc[1], rlSrc[2]);
1443 } else {
1444 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1445 rlSrc[0], rlSrc[1], rlSrc[2]);
1446 }
1447 break;
1448
buzbee101305f2012-06-28 18:00:56 -07001449 case Instruction::IGET:
1450 if (rlDest.fp) {
1451 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001452 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001453 } else {
1454 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001455 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001456 }
buzbee2cfc6392012-05-07 14:51:40 -07001457 break;
buzbee101305f2012-06-28 18:00:56 -07001458 case Instruction::IGET_OBJECT:
1459 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001460 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001461 break;
1462 case Instruction::IGET_BOOLEAN:
1463 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001464 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001465 break;
1466 case Instruction::IGET_BYTE:
1467 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001468 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001469 break;
1470 case Instruction::IGET_CHAR:
1471 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001472 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001473 break;
1474 case Instruction::IGET_SHORT:
1475 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001476 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001477 break;
1478 case Instruction::IGET_WIDE:
1479 if (rlDest.fp) {
1480 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001481 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001482 } else {
1483 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001484 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001485 }
1486 break;
1487 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001488 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001489 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1490 rlSrc[0], rlSrc[1], vC);
1491 } else {
1492 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1493 rlSrc[0], rlSrc[1], vC);
1494 }
1495 break;
1496 case Instruction::IPUT_OBJECT:
1497 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1498 rlSrc[0], rlSrc[1], vC);
1499 break;
1500 case Instruction::IPUT_BOOLEAN:
1501 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1502 rlSrc[0], rlSrc[1], vC);
1503 break;
1504 case Instruction::IPUT_BYTE:
1505 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1506 rlSrc[0], rlSrc[1], vC);
1507 break;
1508 case Instruction::IPUT_CHAR:
1509 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1510 rlSrc[0], rlSrc[1], vC);
1511 break;
1512 case Instruction::IPUT_SHORT:
1513 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1514 rlSrc[0], rlSrc[1], vC);
1515 break;
1516 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001517 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001518 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1519 rlSrc[0], rlSrc[1], vC);
1520 } else {
1521 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1522 rlSrc[0], rlSrc[1], vC);
1523 }
buzbee2cfc6392012-05-07 14:51:40 -07001524 break;
1525
1526 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001527 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001528 break;
1529
buzbee76592632012-06-29 15:18:35 -07001530 case Instruction::LONG_TO_INT:
1531 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1532 break;
1533
buzbee101305f2012-06-28 18:00:56 -07001534 case Instruction::INT_TO_LONG:
1535 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001536 break;
1537
buzbee101305f2012-06-28 18:00:56 -07001538 case Instruction::INT_TO_CHAR:
1539 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1540 greenland::IntrinsicHelper::IntToChar);
1541 break;
1542 case Instruction::INT_TO_BYTE:
1543 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1544 greenland::IntrinsicHelper::IntToByte);
1545 break;
1546 case Instruction::INT_TO_SHORT:
1547 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1548 greenland::IntrinsicHelper::IntToShort);
1549 break;
1550
buzbee76592632012-06-29 15:18:35 -07001551 case Instruction::INT_TO_FLOAT:
1552 case Instruction::LONG_TO_FLOAT:
1553 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001554 break;
1555
buzbee76592632012-06-29 15:18:35 -07001556 case Instruction::INT_TO_DOUBLE:
1557 case Instruction::LONG_TO_DOUBLE:
1558 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001559 break;
1560
buzbee76592632012-06-29 15:18:35 -07001561 case Instruction::FLOAT_TO_DOUBLE:
1562 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001563 break;
1564
buzbee76592632012-06-29 15:18:35 -07001565 case Instruction::DOUBLE_TO_FLOAT:
1566 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001567 break;
1568
1569 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001570 case Instruction::NEG_INT:
1571 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001572 break;
1573
1574 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001575 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001576 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001577 break;
1578
buzbee76592632012-06-29 15:18:35 -07001579 case Instruction::NOT_LONG:
1580 case Instruction::NOT_INT:
1581 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001582 break;
1583
buzbee2cfc6392012-05-07 14:51:40 -07001584 case Instruction::FLOAT_TO_INT:
buzbee2cfc6392012-05-07 14:51:40 -07001585 case Instruction::DOUBLE_TO_INT:
buzbee76592632012-06-29 15:18:35 -07001586 convertFPToInt(cUnit, cUnit->irb->getInt32Ty(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001587 break;
1588
buzbee76592632012-06-29 15:18:35 -07001589 case Instruction::FLOAT_TO_LONG:
1590 case Instruction::DOUBLE_TO_LONG:
1591 convertFPToInt(cUnit, cUnit->irb->getInt64Ty(), rlDest, rlSrc[0]);
1592 break;
1593
1594 case Instruction::CMPL_FLOAT:
1595 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1596 rlDest, rlSrc[0], rlSrc[1]);
1597 break;
1598 case Instruction::CMPG_FLOAT:
1599 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1600 rlDest, rlSrc[0], rlSrc[1]);
1601 break;
1602 case Instruction::CMPL_DOUBLE:
1603 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1604 rlDest, rlSrc[0], rlSrc[1]);
1605 break;
1606 case Instruction::CMPG_DOUBLE:
1607 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1608 rlDest, rlSrc[0], rlSrc[1]);
1609 break;
1610 case Instruction::CMP_LONG:
1611 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1612 rlDest, rlSrc[0], rlSrc[1]);
1613 break;
1614
buzbee76592632012-06-29 15:18:35 -07001615 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001616 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001617 break;
1618
1619 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001620 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001621 break;
buzbee2cfc6392012-05-07 14:51:40 -07001622
1623 default:
buzbee32412962012-06-26 16:27:56 -07001624 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001625 res = true;
1626 }
buzbeeb03f4872012-06-11 15:22:11 -07001627 if (objectDefinition) {
1628 setShadowFrameEntry(cUnit, (llvm::Value*)
1629 cUnit->llvmValues.elemList[rlDest.origSReg]);
1630 }
buzbee2cfc6392012-05-07 14:51:40 -07001631 return res;
1632}
1633
1634/* Extended MIR instructions like PHI */
1635void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1636 llvm::BasicBlock* llvmBB)
1637{
1638
1639 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1640 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001641 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001642 /*
1643 * The Art compiler's Phi nodes only handle 32-bit operands,
1644 * representing wide values using a matched set of Phi nodes
1645 * for the lower and upper halves. In the llvm world, we only
1646 * want a single Phi for wides. Here we will simply discard
1647 * the Phi node representing the high word.
1648 */
1649 if (rlDest.highWord) {
1650 return; // No Phi node - handled via low word
1651 }
1652 int* incoming = (int*)mir->dalvikInsn.vB;
buzbee2cfc6392012-05-07 14:51:40 -07001653 llvm::Type* phiType =
1654 llvmTypeFromLocRec(cUnit, rlDest);
1655 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1656 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1657 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001658 // Don't check width here.
1659 loc = oatGetRawSrc(cUnit, mir, i);
1660 DCHECK_EQ(rlDest.wide, loc.wide);
1661 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1662 DCHECK_EQ(rlDest.fp, loc.fp);
1663 DCHECK_EQ(rlDest.core, loc.core);
1664 DCHECK_EQ(rlDest.ref, loc.ref);
buzbee2cfc6392012-05-07 14:51:40 -07001665 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
1666 getLLVMBlock(cUnit, incoming[i]));
1667 }
1668 defineValue(cUnit, phi, rlDest.origSReg);
1669 break;
1670 }
1671 case kMirOpCopy: {
1672 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1673 break;
1674 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001675 case kMirOpNop:
1676 if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
1677 (bb->fallThrough == NULL)) {
1678 cUnit->irb->CreateUnreachable();
1679 }
1680 break;
1681
buzbee2cfc6392012-05-07 14:51:40 -07001682#if defined(TARGET_ARM)
1683 case kMirOpFusedCmplFloat:
1684 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1685 break;
1686 case kMirOpFusedCmpgFloat:
1687 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1688 break;
1689 case kMirOpFusedCmplDouble:
1690 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1691 break;
1692 case kMirOpFusedCmpgDouble:
1693 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1694 break;
1695 case kMirOpFusedCmpLong:
1696 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1697 break;
1698#endif
1699 default:
1700 break;
1701 }
1702}
1703
1704void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1705{
1706 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001707 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001708 arrayRef.push_back(cUnit->irb->getInt32(offset));
1709 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1710 cUnit->irb->SetDexOffset(node);
1711}
1712
1713// Attach method info as metadata to special intrinsic
1714void setMethodInfo(CompilationUnit* cUnit)
1715{
1716 // We don't want dex offset on this
1717 cUnit->irb->SetDexOffset(NULL);
1718 greenland::IntrinsicHelper::IntrinsicId id;
1719 id = greenland::IntrinsicHelper::MethodInfo;
1720 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1721 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1722 llvm::SmallVector<llvm::Value*, 2> regInfo;
1723 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1724 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1725 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1726 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1727 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1728 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1729 inst->setMetadata("RegInfo", regInfoNode);
1730 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1731 llvm::SmallVector<llvm::Value*, 50> pmap;
1732 for (int i = 0; i < promoSize; i++) {
1733 PromotionMap* p = &cUnit->promotionMap[i];
1734 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1735 ((p->fpReg & 0xff) << 16) |
1736 ((p->coreReg & 0xff) << 8) |
1737 ((p->fpLocation & 0xf) << 4) |
1738 (p->coreLocation & 0xf);
1739 pmap.push_back(cUnit->irb->getInt32(mapData));
1740 }
1741 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1742 inst->setMetadata("PromotionMap", mapNode);
1743 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1744}
1745
1746/* Handle the content in each basic block */
1747bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1748{
1749 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1750 cUnit->irb->SetInsertPoint(llvmBB);
1751 setDexOffset(cUnit, bb->startOffset);
1752
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001753 if (cUnit->printMe) {
1754 LOG(INFO) << "................................";
1755 LOG(INFO) << "Block id " << bb->id;
1756 if (llvmBB != NULL) {
1757 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1758 } else {
1759 LOG(INFO) << "llvmBB is NULL";
1760 }
1761 }
1762
buzbee2cfc6392012-05-07 14:51:40 -07001763 if (bb->blockType == kEntryBlock) {
1764 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001765 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1766 cUnit->numDalvikRegisters, true,
1767 kAllocMisc);
1768 for (int i = 0; i < cUnit->numSSARegs; i++) {
1769 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1770 }
1771 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1772 if (canBeRef[i]) {
1773 cUnit->numShadowFrameEntries++;
1774 }
1775 }
1776 if (cUnit->numShadowFrameEntries > 0) {
1777 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1778 cUnit->numShadowFrameEntries, true,
1779 kAllocMisc);
1780 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1781 if (canBeRef[i]) {
1782 cUnit->shadowMap[j++] = i;
1783 }
1784 }
1785 greenland::IntrinsicHelper::IntrinsicId id =
1786 greenland::IntrinsicHelper::AllocaShadowFrame;
1787 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1788 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1789 cUnit->irb->CreateCall(func, entries);
1790 }
buzbee2cfc6392012-05-07 14:51:40 -07001791 } else if (bb->blockType == kExitBlock) {
1792 /*
1793 * Because of the differences between how MIR/LIR and llvm handle exit
1794 * blocks, we won't explicitly covert them. On the llvm-to-lir
1795 * path, it will need to be regenereated.
1796 */
1797 return false;
buzbee6969d502012-06-15 16:40:31 -07001798 } else if (bb->blockType == kExceptionHandling) {
1799 /*
1800 * Because we're deferring null checking, delete the associated empty
1801 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001802 */
1803 llvmBB->eraseFromParent();
1804 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001805 }
1806
1807 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1808
1809 setDexOffset(cUnit, mir->offset);
1810
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001811 int opcode = mir->dalvikInsn.opcode;
1812 Instruction::Format dalvikFormat =
1813 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001814
1815 /* If we're compiling for the debugger, generate an update callout */
1816 if (cUnit->genDebugger) {
1817 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1818 //genDebuggerUpdate(cUnit, mir->offset);
1819 }
1820
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001821 if (opcode == kMirOpCheck) {
1822 // Combine check and work halves of throwing instruction.
1823 MIR* workHalf = mir->meta.throwInsn;
1824 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
1825 opcode = mir->dalvikInsn.opcode;
1826 SSARepresentation* ssaRep = workHalf->ssaRep;
1827 workHalf->ssaRep = mir->ssaRep;
1828 mir->ssaRep = ssaRep;
1829 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1830 if (bb->successorBlockList.blockListType == kCatch) {
1831 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
1832 greenland::IntrinsicHelper::CatchTargets);
1833 llvm::Value* switchKey =
1834 cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
1835 GrowableListIterator iter;
1836 oatGrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
1837 // New basic block to use for work half
1838 llvm::BasicBlock* workBB =
1839 llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
1840 llvm::SwitchInst* sw =
1841 cUnit->irb->CreateSwitch(switchKey, workBB,
1842 bb->successorBlockList.blocks.numUsed);
1843 while (true) {
1844 SuccessorBlockInfo *successorBlockInfo =
1845 (SuccessorBlockInfo *) oatGrowableListIteratorNext(&iter);
1846 if (successorBlockInfo == NULL) break;
1847 llvm::BasicBlock *target =
1848 getLLVMBlock(cUnit, successorBlockInfo->block->id);
1849 int typeIndex = successorBlockInfo->key;
1850 sw->addCase(cUnit->irb->getInt32(typeIndex), target);
1851 }
1852 llvmBB = workBB;
1853 cUnit->irb->SetInsertPoint(llvmBB);
1854 }
1855 }
1856
1857 if (opcode >= kMirOpFirst) {
buzbee2cfc6392012-05-07 14:51:40 -07001858 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1859 continue;
1860 }
1861
1862 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1863 NULL /* labelList */);
1864 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001865 Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001866 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001867 mir->offset, opcode,
buzbee2cfc6392012-05-07 14:51:40 -07001868 Instruction::Name(dalvikOpcode),
1869 dalvikFormat);
1870 }
1871 }
1872
buzbee4be777b2012-07-12 14:38:18 -07001873 if (bb->blockType == kEntryBlock) {
1874 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1875 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001876 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1877 }
1878
1879 return false;
1880}
1881
buzbee4f4dfc72012-07-02 14:54:44 -07001882char remapShorty(char shortyType) {
1883 /*
1884 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1885 * and longs/doubles are represented as a pair of registers. When sub-word
1886 * arguments (and method results) are passed, they are extended to Dalvik
1887 * virtual register containers. Because llvm is picky about type consistency,
1888 * we must either cast the "real" type to 32-bit container multiple Dalvik
1889 * register types, or always use the expanded values.
1890 * Here, we're doing the latter. We map the shorty signature to container
1891 * types (which is valid so long as we always do a real expansion of passed
1892 * arguments and field loads).
1893 */
1894 switch(shortyType) {
1895 case 'Z' : shortyType = 'I'; break;
1896 case 'B' : shortyType = 'I'; break;
1897 case 'S' : shortyType = 'I'; break;
1898 case 'C' : shortyType = 'I'; break;
1899 default: break;
1900 }
1901 return shortyType;
1902}
1903
buzbee2cfc6392012-05-07 14:51:40 -07001904llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1905
1906 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001907 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001908 greenland::kAccurate);
1909
1910 // Get argument type
1911 std::vector<llvm::Type*> args_type;
1912
1913 // method object
1914 args_type.push_back(cUnit->irb->GetJMethodTy());
1915
1916 // Do we have a "this"?
1917 if ((cUnit->access_flags & kAccStatic) == 0) {
1918 args_type.push_back(cUnit->irb->GetJObjectTy());
1919 }
1920
1921 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001922 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001923 greenland::kAccurate));
1924 }
1925
1926 return llvm::FunctionType::get(ret_type, args_type, false);
1927}
1928
1929bool createFunction(CompilationUnit* cUnit) {
1930 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1931 /* with_signature */ false));
1932 llvm::FunctionType* func_type = getFunctionType(cUnit);
1933
1934 if (func_type == NULL) {
1935 return false;
1936 }
1937
1938 cUnit->func = llvm::Function::Create(func_type,
1939 llvm::Function::ExternalLinkage,
1940 func_name, cUnit->module);
1941
1942 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1943 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1944
1945 arg_iter->setName("method");
1946 ++arg_iter;
1947
1948 int startSReg = cUnit->numRegs;
1949
1950 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1951 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1952 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1953 }
1954
1955 return true;
1956}
1957
1958bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1959{
1960 // Skip the exit block
1961 if (bb->blockType == kExitBlock) {
1962 cUnit->idToBlockMap.Put(bb->id, NULL);
1963 } else {
1964 int offset = bb->startOffset;
1965 bool entryBlock = (bb->blockType == kEntryBlock);
1966 llvm::BasicBlock* llvmBB =
1967 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
Elliott Hughes74847412012-06-20 18:10:21 -07001968 StringPrintf(kLabelFormat, offset, bb->id),
buzbee2cfc6392012-05-07 14:51:40 -07001969 cUnit->func);
1970 if (entryBlock) {
1971 cUnit->entryBB = llvmBB;
1972 cUnit->placeholderBB =
1973 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1974 cUnit->func);
1975 }
1976 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1977 }
1978 return false;
1979}
1980
1981
1982/*
1983 * Convert MIR to LLVM_IR
1984 * o For each ssa name, create LLVM named value. Type these
1985 * appropriately, and ignore high half of wide and double operands.
1986 * o For each MIR basic block, create an LLVM basic block.
1987 * o Iterate through the MIR a basic block at a time, setting arguments
1988 * to recovered ssa name.
1989 */
1990void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
1991{
1992 initIR(cUnit);
1993 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
1994
1995 // Create the function
1996 createFunction(cUnit);
1997
1998 // Create an LLVM basic block for each MIR block in dfs preorder
1999 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
2000 kPreOrderDFSTraversal, false /* isIterative */);
2001 /*
2002 * Create an llvm named value for each MIR SSA name. Note: we'll use
2003 * placeholders for all non-argument values (because we haven't seen
2004 * the definition yet).
2005 */
2006 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2007 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2008 arg_iter++; /* Skip path method */
2009 for (int i = 0; i < cUnit->numSSARegs; i++) {
2010 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07002011 RegLocation rlTemp = cUnit->regLocation[i];
2012 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07002013 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
2014 } else if ((i < cUnit->numRegs) ||
2015 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07002016 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
2017 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07002018 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
2019 val->setName(llvmSSAName(cUnit, i));
buzbee2cfc6392012-05-07 14:51:40 -07002020 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
buzbee2cfc6392012-05-07 14:51:40 -07002021 } else {
2022 // Recover previously-created argument values
2023 llvm::Value* argVal = arg_iter++;
2024 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
2025 }
2026 }
buzbee2cfc6392012-05-07 14:51:40 -07002027
2028 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
2029 kPreOrderDFSTraversal, false /* Iterative */);
2030
buzbee4be777b2012-07-12 14:38:18 -07002031 /*
2032 * In a few rare cases of verification failure, the verifier will
2033 * replace one or more Dalvik opcodes with the special
2034 * throw-verification-failure opcode. This can leave the SSA graph
2035 * in an invalid state, as definitions may be lost, while uses retained.
2036 * To work around this problem, we insert placeholder definitions for
2037 * all Dalvik SSA regs in the "placeholder" block. Here, after
2038 * bitcode conversion is complete, we examine those placeholder definitions
2039 * and delete any with no references (which normally is all of them).
2040 *
2041 * If any definitions remain, we link the placeholder block into the
2042 * CFG. Otherwise, it is deleted.
2043 */
2044 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
2045 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
2046 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2047 DCHECK(inst != NULL);
2048 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2049 DCHECK(val != NULL);
2050 if (val->getNumUses() == 0) {
2051 inst->eraseFromParent();
2052 }
2053 }
2054 setDexOffset(cUnit, 0);
2055 if (cUnit->placeholderBB->empty()) {
2056 cUnit->placeholderBB->eraseFromParent();
2057 } else {
2058 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2059 cUnit->irb->CreateBr(cUnit->entryTargetBB);
2060 cUnit->entryTargetBB = cUnit->placeholderBB;
2061 }
2062 cUnit->irb->SetInsertPoint(cUnit->entryBB);
2063 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07002064
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002065 if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
2066 if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
2067 LOG(INFO) << "Bitcode verification FAILED for "
2068 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
2069 << " of size " << cUnit->insnsSize;
2070 cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
2071 }
2072 }
buzbee2cfc6392012-05-07 14:51:40 -07002073
buzbeead8f15e2012-06-18 14:49:45 -07002074 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
2075 // Write bitcode to file
2076 std::string errmsg;
2077 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
2078 oatReplaceSpecialChars(fname);
2079 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07002080 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002081
buzbeead8f15e2012-06-18 14:49:45 -07002082 llvm::OwningPtr<llvm::tool_output_file> out_file(
2083 new llvm::tool_output_file(fname.c_str(), errmsg,
2084 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002085
buzbeead8f15e2012-06-18 14:49:45 -07002086 if (!errmsg.empty()) {
2087 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2088 }
2089
2090 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2091 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002092 }
buzbee2cfc6392012-05-07 14:51:40 -07002093}
2094
2095RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2096 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002097 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002098 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2099 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002100 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002101 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002102 // FIXME: need to be more robust, handle FP and be in a position to
2103 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002104 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2105 memset(&res, 0, sizeof(res));
2106 res.location = kLocPhysReg;
2107 res.lowReg = oatAllocTemp(cUnit);
2108 res.home = true;
2109 res.sRegLow = INVALID_SREG;
2110 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002111 llvm::Type* ty = val->getType();
2112 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2113 (ty == cUnit->irb->getDoubleTy()));
2114 if (res.wide) {
2115 res.highReg = oatAllocTemp(cUnit);
2116 }
buzbee4f1181f2012-06-22 13:52:12 -07002117 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002118 } else {
2119 DCHECK_EQ(valName[0], 'v');
2120 int baseSReg = INVALID_SREG;
2121 sscanf(valName.c_str(), "v%d_", &baseSReg);
2122 res = cUnit->regLocation[baseSReg];
2123 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002124 }
2125 } else {
2126 res = it->second;
2127 }
2128 return res;
2129}
2130
2131Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2132{
2133 Instruction::Code res = Instruction::NOP;
2134 if (isWide) {
2135 switch(op) {
2136 case kOpAdd: res = Instruction::ADD_LONG; break;
2137 case kOpSub: res = Instruction::SUB_LONG; break;
2138 case kOpMul: res = Instruction::MUL_LONG; break;
2139 case kOpDiv: res = Instruction::DIV_LONG; break;
2140 case kOpRem: res = Instruction::REM_LONG; break;
2141 case kOpAnd: res = Instruction::AND_LONG; break;
2142 case kOpOr: res = Instruction::OR_LONG; break;
2143 case kOpXor: res = Instruction::XOR_LONG; break;
2144 case kOpLsl: res = Instruction::SHL_LONG; break;
2145 case kOpLsr: res = Instruction::USHR_LONG; break;
2146 case kOpAsr: res = Instruction::SHR_LONG; break;
2147 default: LOG(FATAL) << "Unexpected OpKind " << op;
2148 }
2149 } else if (isConst){
2150 switch(op) {
2151 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2152 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2153 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2154 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2155 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2156 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2157 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2158 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2159 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2160 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2161 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2162 default: LOG(FATAL) << "Unexpected OpKind " << op;
2163 }
2164 } else {
2165 switch(op) {
2166 case kOpAdd: res = Instruction::ADD_INT; break;
2167 case kOpSub: res = Instruction::SUB_INT; break;
2168 case kOpMul: res = Instruction::MUL_INT; break;
2169 case kOpDiv: res = Instruction::DIV_INT; break;
2170 case kOpRem: res = Instruction::REM_INT; break;
2171 case kOpAnd: res = Instruction::AND_INT; break;
2172 case kOpOr: res = Instruction::OR_INT; break;
2173 case kOpXor: res = Instruction::XOR_INT; break;
2174 case kOpLsl: res = Instruction::SHL_INT; break;
2175 case kOpLsr: res = Instruction::USHR_INT; break;
2176 case kOpAsr: res = Instruction::SHR_INT; break;
2177 default: LOG(FATAL) << "Unexpected OpKind " << op;
2178 }
2179 }
2180 return res;
2181}
2182
buzbee4f1181f2012-06-22 13:52:12 -07002183Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2184{
2185 Instruction::Code res = Instruction::NOP;
2186 if (isWide) {
2187 switch(op) {
2188 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2189 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2190 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2191 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2192 case kOpRem: res = Instruction::REM_DOUBLE; break;
2193 default: LOG(FATAL) << "Unexpected OpKind " << op;
2194 }
2195 } else {
2196 switch(op) {
2197 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2198 case kOpSub: res = Instruction::SUB_FLOAT; break;
2199 case kOpMul: res = Instruction::MUL_FLOAT; break;
2200 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2201 case kOpRem: res = Instruction::REM_FLOAT; break;
2202 default: LOG(FATAL) << "Unexpected OpKind " << op;
2203 }
2204 }
2205 return res;
2206}
2207
2208void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2209{
2210 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002211 /*
2212 * Normally, we won't ever generate an FP operation with an immediate
2213 * operand (not supported in Dex instruction set). However, the IR builder
2214 * may insert them - in particular for createNegFP. Recognize this case
2215 * and deal with it.
2216 */
2217 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2218 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2219 DCHECK(op2C == NULL);
2220 if ((op1C != NULL) && (op == kOpSub)) {
2221 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2222 if (rlDest.wide) {
2223 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2224 } else {
2225 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2226 }
buzbee4f1181f2012-06-22 13:52:12 -07002227 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002228 DCHECK(op1C == NULL);
2229 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2230 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2231 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2232 if (rlDest.wide) {
2233 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2234 } else {
2235 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2236 }
buzbee4f1181f2012-06-22 13:52:12 -07002237 }
2238}
2239
buzbee101305f2012-06-28 18:00:56 -07002240void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2241 Instruction::Code opcode)
2242{
2243 RegLocation rlDest = getLoc(cUnit, inst);
2244 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2245 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2246}
2247
buzbee76592632012-06-29 15:18:35 -07002248void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2249{
2250 RegLocation rlDest = getLoc(cUnit, inst);
2251 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2252 Instruction::Code opcode;
2253 if (rlDest.wide) {
2254 if (rlSrc.wide) {
2255 opcode = Instruction::LONG_TO_DOUBLE;
2256 } else {
2257 opcode = Instruction::INT_TO_DOUBLE;
2258 }
2259 } else {
2260 if (rlSrc.wide) {
2261 opcode = Instruction::LONG_TO_FLOAT;
2262 } else {
2263 opcode = Instruction::INT_TO_FLOAT;
2264 }
2265 }
2266 genConversion(cUnit, opcode, rlDest, rlSrc);
2267}
2268
2269void cvtFPToInt(CompilationUnit* cUnit, llvm::Instruction* inst)
2270{
2271 RegLocation rlDest = getLoc(cUnit, inst);
2272 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2273 Instruction::Code opcode;
2274 if (rlDest.wide) {
2275 if (rlSrc.wide) {
2276 opcode = Instruction::DOUBLE_TO_LONG;
2277 } else {
2278 opcode = Instruction::FLOAT_TO_LONG;
2279 }
2280 } else {
2281 if (rlSrc.wide) {
2282 opcode = Instruction::DOUBLE_TO_INT;
2283 } else {
2284 opcode = Instruction::FLOAT_TO_INT;
2285 }
2286 }
2287 genConversion(cUnit, opcode, rlDest, rlSrc);
2288}
2289
2290void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2291{
2292 RegLocation rlDest = getLoc(cUnit, inst);
2293 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2294 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2295}
2296
2297void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2298{
2299 RegLocation rlDest = getLoc(cUnit, inst);
2300 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2301 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2302 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2303 storeValue(cUnit, rlDest, rlSrc);
2304}
2305
2306void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2307{
2308 RegLocation rlDest = getLoc(cUnit, inst);
2309 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2310 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2311}
2312
2313
buzbee101305f2012-06-28 18:00:56 -07002314void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2315{
2316 // TODO: evaluate src/tgt types and add general support for more than int to long
2317 RegLocation rlDest = getLoc(cUnit, inst);
2318 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2319 DCHECK(rlDest.wide);
2320 DCHECK(!rlSrc.wide);
2321 DCHECK(!rlDest.fp);
2322 DCHECK(!rlSrc.fp);
2323 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2324 if (rlSrc.location == kLocPhysReg) {
2325 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2326 } else {
2327 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2328 }
2329 if (isSigned) {
2330 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2331 } else {
2332 loadConstant(cUnit, rlResult.highReg, 0);
2333 }
2334 storeValueWide(cUnit, rlDest, rlResult);
2335}
2336
buzbee2cfc6392012-05-07 14:51:40 -07002337void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2338{
2339 RegLocation rlDest = getLoc(cUnit, inst);
2340 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002341 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002342 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2343 if ((op == kOpSub) && (lhsImm != NULL)) {
2344 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002345 if (rlSrc1.wide) {
2346 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2347 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2348 } else {
2349 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2350 lhsImm->getSExtValue());
2351 }
buzbee4f1181f2012-06-22 13:52:12 -07002352 return;
2353 }
2354 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002355 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2356 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002357 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2358 if (!rlDest.wide && (constRhs != NULL)) {
buzbee2cfc6392012-05-07 14:51:40 -07002359 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
buzbee9a2487f2012-07-26 14:01:13 -07002360 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002361 } else {
2362 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002363 RegLocation rlSrc2;
2364 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002365 // ir_builder converts NOT_LONG to xor src, -1. Restore
2366 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2367 DCHECK_EQ(-1L, constRhs->getSExtValue());
2368 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002369 rlSrc2 = rlSrc1;
2370 } else {
2371 rlSrc2 = getLoc(cUnit, rhs);
2372 }
buzbee2cfc6392012-05-07 14:51:40 -07002373 if (rlDest.wide) {
2374 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2375 } else {
2376 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2377 }
2378 }
2379}
2380
buzbee2a83e8f2012-07-13 16:42:30 -07002381void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2382 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002383{
buzbee2a83e8f2012-07-13 16:42:30 -07002384 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2385 RegLocation rlDest = getLoc(cUnit, callInst);
2386 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2387 llvm::Value* rhs = callInst->getArgOperand(1);
2388 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2389 DCHECK(!rlDest.wide);
2390 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002391 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002392 RegLocation rlShift = getLoc(cUnit, rhs);
2393 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2394 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2395 } else {
2396 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2397 }
buzbee101305f2012-06-28 18:00:56 -07002398 }
2399}
2400
buzbee2cfc6392012-05-07 14:51:40 -07002401void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2402{
2403 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2404 DCHECK(brInst != NULL);
2405 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2406 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2407 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2408}
2409
2410void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2411{
2412 // Nop - these have already been processed
2413}
2414
2415void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2416{
2417 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2418 llvm::Value* retVal = retInst->getReturnValue();
2419 if (retVal != NULL) {
2420 RegLocation rlSrc = getLoc(cUnit, retVal);
2421 if (rlSrc.wide) {
2422 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2423 } else {
2424 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2425 }
2426 }
2427 genExitSequence(cUnit);
2428}
2429
2430ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2431{
2432 ConditionCode res = kCondAl;
2433 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002434 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002435 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2436 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2437 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002438 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002439 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002440 default: LOG(FATAL) << "Unexpected llvm condition";
2441 }
2442 return res;
2443}
2444
2445void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2446{
2447 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2448 UNIMPLEMENTED(FATAL);
2449}
2450
2451void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2452 llvm::BranchInst* brInst)
2453{
2454 // Get targets
2455 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2456 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2457 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2458 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2459 // Get comparison operands
2460 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2461 ConditionCode cond = getCond(iCmpInst->getPredicate());
2462 llvm::Value* lhs = iCmpInst->getOperand(0);
2463 // Not expecting a constant as 1st operand
2464 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2465 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2466 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2467 llvm::Value* rhs = inst->getOperand(1);
2468#if defined(TARGET_MIPS)
2469 // Compare and branch in one shot
2470 (void)taken;
2471 (void)cond;
2472 (void)rhs;
2473 UNIMPLEMENTED(FATAL);
2474#else
2475 //Compare, then branch
2476 // TODO: handle fused CMP_LONG/IF_xxZ case
2477 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2478 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002479 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2480 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002481 } else {
2482 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2483 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2484 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2485 }
2486 opCondBranch(cUnit, cond, taken);
2487#endif
2488 // Fallthrough
2489 opUnconditionalBranch(cUnit, fallThrough);
2490}
2491
2492void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2493 llvm::Function* callee)
2494{
2495 UNIMPLEMENTED(FATAL);
2496}
2497
buzbee2cfc6392012-05-07 14:51:40 -07002498void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2499{
buzbee4f1181f2012-06-22 13:52:12 -07002500 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002501 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2502 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002503 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2504 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002505 if (rlSrc.wide) {
2506 storeValueWide(cUnit, rlDest, rlSrc);
2507 } else {
2508 storeValue(cUnit, rlDest, rlSrc);
2509 }
2510}
2511
2512// Note: Immediate arg is a ConstantInt regardless of result type
2513void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2514{
buzbee4f1181f2012-06-22 13:52:12 -07002515 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002516 llvm::ConstantInt* src =
2517 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2518 uint64_t immval = src->getZExtValue();
2519 RegLocation rlDest = getLoc(cUnit, callInst);
2520 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2521 if (rlDest.wide) {
2522 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2523 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2524 storeValueWide(cUnit, rlDest, rlResult);
2525 } else {
2526 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2527 storeValue(cUnit, rlDest, rlResult);
2528 }
2529}
2530
buzbee101305f2012-06-28 18:00:56 -07002531void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2532 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002533{
buzbee4f1181f2012-06-22 13:52:12 -07002534 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002535 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002536 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002537 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002538 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002539 if (isString) {
2540 genConstString(cUnit, index, rlDest);
2541 } else {
2542 genConstClass(cUnit, index, rlDest);
2543 }
2544}
2545
2546void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2547{
2548 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2549 llvm::ConstantInt* offsetVal =
2550 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2551 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2552 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002553}
2554
buzbee4f1181f2012-06-22 13:52:12 -07002555void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2556{
buzbee32412962012-06-26 16:27:56 -07002557 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002558 llvm::ConstantInt* typeIdxVal =
2559 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2560 uint32_t typeIdx = typeIdxVal->getZExtValue();
2561 RegLocation rlDest = getLoc(cUnit, callInst);
2562 genNewInstance(cUnit, typeIdx, rlDest);
2563}
2564
buzbee8fa0fda2012-06-27 15:44:52 -07002565void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2566{
2567 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2568 llvm::ConstantInt* typeIdxVal =
2569 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2570 uint32_t typeIdx = typeIdxVal->getZExtValue();
2571 llvm::Value* len = callInst->getArgOperand(1);
2572 RegLocation rlLen = getLoc(cUnit, len);
2573 RegLocation rlDest = getLoc(cUnit, callInst);
2574 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2575}
2576
2577void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2578{
2579 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2580 llvm::ConstantInt* typeIdxVal =
2581 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2582 uint32_t typeIdx = typeIdxVal->getZExtValue();
2583 llvm::Value* src = callInst->getArgOperand(1);
2584 RegLocation rlSrc = getLoc(cUnit, src);
2585 RegLocation rlDest = getLoc(cUnit, callInst);
2586 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2587}
2588
buzbee32412962012-06-26 16:27:56 -07002589void cvtThrowVerificationError(CompilationUnit* cUnit, llvm::CallInst* callInst)
2590{
2591 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2592 llvm::ConstantInt* info1 =
2593 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2594 llvm::ConstantInt* info2 =
2595 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2596 genThrowVerificationError(cUnit, info1->getZExtValue(), info2->getZExtValue());
2597}
2598
2599void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2600{
2601 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2602 llvm::Value* src = callInst->getArgOperand(0);
2603 RegLocation rlSrc = getLoc(cUnit, src);
2604 genThrow(cUnit, rlSrc);
2605}
2606
buzbee8fa0fda2012-06-27 15:44:52 -07002607void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2608 llvm::CallInst* callInst)
2609{
2610 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2611 llvm::ConstantInt* optFlags =
2612 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2613 llvm::Value* src = callInst->getArgOperand(1);
2614 RegLocation rlSrc = getLoc(cUnit, src);
2615 if (isEnter) {
2616 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2617 } else {
2618 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2619 }
2620}
2621
buzbee76592632012-06-29 15:18:35 -07002622void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002623{
2624 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2625 llvm::ConstantInt* optFlags =
2626 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2627 llvm::Value* src = callInst->getArgOperand(1);
2628 RegLocation rlSrc = getLoc(cUnit, src);
2629 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2630 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2631 RegLocation rlDest = getLoc(cUnit, callInst);
2632 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2633 int lenOffset = Array::LengthOffset().Int32Value();
2634 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2635 storeValue(cUnit, rlDest, rlResult);
2636}
2637
buzbee32412962012-06-26 16:27:56 -07002638void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2639{
2640 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
2641 int exOffset = Thread::ExceptionOffset().Int32Value();
2642 RegLocation rlDest = getLoc(cUnit, callInst);
2643 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2644#if defined(TARGET_X86)
2645 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
2646 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
2647#else
2648 int resetReg = oatAllocTemp(cUnit);
2649 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
2650 loadConstant(cUnit, resetReg, 0);
2651 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
2652 oatFreeTemp(cUnit, resetReg);
2653#endif
2654 storeValue(cUnit, rlDest, rlResult);
2655}
2656
buzbee4f1181f2012-06-22 13:52:12 -07002657void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2658 bool isObject)
2659{
buzbee32412962012-06-26 16:27:56 -07002660 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002661 llvm::ConstantInt* typeIdxVal =
2662 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2663 uint32_t typeIdx = typeIdxVal->getZExtValue();
2664 RegLocation rlDest = getLoc(cUnit, callInst);
2665 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2666}
2667
buzbee8fa0fda2012-06-27 15:44:52 -07002668void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2669 bool isObject)
2670{
2671 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2672 llvm::ConstantInt* typeIdxVal =
2673 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2674 uint32_t typeIdx = typeIdxVal->getZExtValue();
2675 llvm::Value* src = callInst->getArgOperand(1);
2676 RegLocation rlSrc = getLoc(cUnit, src);
2677 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2678}
2679
2680void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2681 int scale)
2682{
2683 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2684 llvm::ConstantInt* optFlags =
2685 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2686 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2687 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2688 RegLocation rlDest = getLoc(cUnit, callInst);
2689 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2690 rlDest, scale);
2691}
2692
2693void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002694 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002695{
2696 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2697 llvm::ConstantInt* optFlags =
2698 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2699 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2700 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2701 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002702 if (isObject) {
2703 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2704 rlSrc, scale);
2705 } else {
2706 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2707 rlSrc, scale);
2708 }
2709}
2710
2711void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2712{
2713 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2714}
2715
2716void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2717 OpSize size, int scale)
2718{
2719 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002720}
2721
buzbee101305f2012-06-28 18:00:56 -07002722void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2723 bool isWide, bool isObj)
2724{
2725 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2726 llvm::ConstantInt* optFlags =
2727 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2728 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2729 llvm::ConstantInt* fieldIdx =
2730 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2731 RegLocation rlDest = getLoc(cUnit, callInst);
2732 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2733 size, rlDest, rlObj, isWide, isObj);
2734}
2735
2736void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2737 bool isWide, bool isObj)
2738{
2739 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2740 llvm::ConstantInt* optFlags =
2741 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2742 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2743 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2744 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002745 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002746 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2747 size, rlSrc, rlObj, isWide, isObj);
2748}
2749
2750void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2751{
2752 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2753 llvm::ConstantInt* typeIdx =
2754 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2755 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2756 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2757}
2758
buzbee76592632012-06-29 15:18:35 -07002759void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2760 Instruction::Code opcode)
2761{
2762 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2763 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2764 RegLocation rlDest = getLoc(cUnit, callInst);
2765 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2766}
2767
2768void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2769{
2770 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2771 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2772 RegLocation rlDest = getLoc(cUnit, callInst);
2773 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2774}
2775
buzbeef58c12c2012-07-03 15:06:29 -07002776void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2777{
2778 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2779 DCHECK(swInst != NULL);
2780 llvm::Value* testVal = swInst->getCondition();
2781 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2782 DCHECK(tableOffsetNode != NULL);
2783 llvm::ConstantInt* tableOffsetValue =
2784 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2785 int32_t tableOffset = tableOffsetValue->getSExtValue();
2786 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeea1da8a52012-07-09 14:00:21 -07002787 const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2788 u2 tableMagic = *table;
2789 if (tableMagic == 0x100) {
2790 genPackedSwitch(cUnit, tableOffset, rlSrc);
2791 } else {
2792 DCHECK_EQ(tableMagic, 0x200);
2793 genSparseSwitch(cUnit, tableOffset, rlSrc);
2794 }
buzbeef58c12c2012-07-03 15:06:29 -07002795}
2796
buzbee6969d502012-06-15 16:40:31 -07002797void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002798 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002799{
2800 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2801 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002802 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002803 info->result.location = kLocInvalid;
2804 } else {
2805 info->result = getLoc(cUnit, callInst);
2806 }
2807 llvm::ConstantInt* invokeTypeVal =
2808 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2809 llvm::ConstantInt* methodIndexVal =
2810 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2811 llvm::ConstantInt* optFlagsVal =
2812 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2813 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2814 info->index = methodIndexVal->getZExtValue();
2815 info->optFlags = optFlagsVal->getZExtValue();
2816 info->offset = cUnit->currentDalvikOffset;
2817
buzbee6969d502012-06-15 16:40:31 -07002818 // Count the argument words, and then build argument array.
2819 info->numArgWords = 0;
2820 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2821 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2822 info->numArgWords += tLoc.wide ? 2 : 1;
2823 }
2824 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2825 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2826 // Now, fill in the location records, synthesizing high loc of wide vals
2827 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002828 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002829 if (info->args[next].wide) {
2830 next++;
2831 // TODO: Might make sense to mark this as an invalid loc
2832 info->args[next].origSReg = info->args[next-1].origSReg+1;
2833 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2834 }
2835 next++;
2836 }
buzbee4f4dfc72012-07-02 14:54:44 -07002837 // TODO - rework such that we no longer need isRange
2838 info->isRange = (info->numArgWords > 5);
2839
buzbee76592632012-06-29 15:18:35 -07002840 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002841 genFilledNewArray(cUnit, info);
2842 } else {
2843 genInvoke(cUnit, info);
2844 }
buzbee6969d502012-06-15 16:40:31 -07002845}
2846
buzbeead8f15e2012-06-18 14:49:45 -07002847/* Look up the RegLocation associated with a Value. Must already be defined */
2848RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2849{
2850 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2851 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2852 return it->second;
2853}
2854
buzbee2cfc6392012-05-07 14:51:40 -07002855bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2856{
2857 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2858 // Define the starting label
2859 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2860 // Extract the starting offset from the block's name
2861 if (!isEntry) {
2862 const char* blockName = bb->getName().str().c_str();
2863 int dummy;
Elliott Hughes74847412012-06-20 18:10:21 -07002864 sscanf(blockName, kLabelFormat, &blockLabel->operands[0], &dummy);
buzbee2cfc6392012-05-07 14:51:40 -07002865 }
2866 // Set the label kind
2867 blockLabel->opcode = kPseudoNormalBlockLabel;
2868 // Insert the label
2869 oatAppendLIR(cUnit, blockLabel);
2870
2871 // Free temp registers and reset redundant store tracking */
2872 oatResetRegPool(cUnit);
2873 oatResetDefTracking(cUnit);
2874
2875 //TODO: restore oat incoming liveness optimization
2876 oatClobberAllRegs(cUnit);
2877
buzbee6969d502012-06-15 16:40:31 -07002878 LIR* headLIR = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07002879
2880 if (isEntry) {
2881 cUnit->currentDalvikOffset = 0;
buzbeead8f15e2012-06-18 14:49:45 -07002882 RegLocation* argLocs = (RegLocation*)
2883 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2884 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2885 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2886 for (unsigned i = 0; it != it_end; ++it) {
2887 llvm::Value* val = it;
2888 argLocs[i++] = valToLoc(cUnit, val);
2889 llvm::Type* ty = val->getType();
2890 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2891 argLocs[i++].sRegLow = INVALID_SREG;
2892 }
2893 }
2894 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
buzbee2cfc6392012-05-07 14:51:40 -07002895 }
2896
2897 // Visit all of the instructions in the block
2898 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2899 llvm::Instruction* inst = it;
2900 llvm::BasicBlock::iterator nextIt = ++it;
2901 // Extract the Dalvik offset from the instruction
2902 uint32_t opcode = inst->getOpcode();
2903 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2904 if (dexOffsetNode != NULL) {
2905 llvm::ConstantInt* dexOffsetValue =
2906 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2907 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2908 }
2909
buzbee6969d502012-06-15 16:40:31 -07002910 oatResetRegPool(cUnit);
2911 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2912 oatClobberAllRegs(cUnit);
2913 }
2914
2915 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2916 oatResetDefTracking(cUnit);
2917 }
2918
2919#ifndef NDEBUG
2920 /* Reset temp tracking sanity check */
2921 cUnit->liveSReg = INVALID_SREG;
2922#endif
2923
2924 LIR* boundaryLIR;
2925 const char* instStr = "boundary";
2926 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
2927 (intptr_t) instStr);
2928 cUnit->boundaryMap.Overwrite(cUnit->currentDalvikOffset, boundaryLIR);
2929
2930 /* Remember the first LIR for thisl block*/
2931 if (headLIR == NULL) {
2932 headLIR = boundaryLIR;
2933 headLIR->defMask = ENCODE_ALL;
2934 }
2935
buzbee2cfc6392012-05-07 14:51:40 -07002936 switch(opcode) {
2937
2938 case llvm::Instruction::ICmp: {
2939 llvm::Instruction* nextInst = nextIt;
2940 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2941 if (brInst != NULL /* and... */) {
2942 cvtICmpBr(cUnit, inst, brInst);
2943 ++it;
2944 } else {
2945 cvtICmp(cUnit, inst);
2946 }
2947 }
2948 break;
2949
2950 case llvm::Instruction::Call: {
2951 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2952 llvm::Function* callee = callInst->getCalledFunction();
2953 greenland::IntrinsicHelper::IntrinsicId id =
2954 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2955 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07002956 case greenland::IntrinsicHelper::AllocaShadowFrame:
2957 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07002958 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07002959 // Ignore shadow frame stuff for quick compiler
2960 break;
buzbee2cfc6392012-05-07 14:51:40 -07002961 case greenland::IntrinsicHelper::CopyInt:
2962 case greenland::IntrinsicHelper::CopyObj:
2963 case greenland::IntrinsicHelper::CopyFloat:
2964 case greenland::IntrinsicHelper::CopyLong:
2965 case greenland::IntrinsicHelper::CopyDouble:
2966 cvtCopy(cUnit, callInst);
2967 break;
2968 case greenland::IntrinsicHelper::ConstInt:
2969 case greenland::IntrinsicHelper::ConstObj:
2970 case greenland::IntrinsicHelper::ConstLong:
2971 case greenland::IntrinsicHelper::ConstFloat:
2972 case greenland::IntrinsicHelper::ConstDouble:
2973 cvtConst(cUnit, callInst);
2974 break;
buzbee4f1181f2012-06-22 13:52:12 -07002975 case greenland::IntrinsicHelper::DivInt:
2976 case greenland::IntrinsicHelper::DivLong:
2977 cvtBinOp(cUnit, kOpDiv, inst);
2978 break;
2979 case greenland::IntrinsicHelper::RemInt:
2980 case greenland::IntrinsicHelper::RemLong:
2981 cvtBinOp(cUnit, kOpRem, inst);
2982 break;
buzbee2cfc6392012-05-07 14:51:40 -07002983 case greenland::IntrinsicHelper::MethodInfo:
buzbeead8f15e2012-06-18 14:49:45 -07002984 // Already dealt with - just ignore it here.
buzbee2cfc6392012-05-07 14:51:40 -07002985 break;
2986 case greenland::IntrinsicHelper::CheckSuspend:
2987 genSuspendTest(cUnit, 0 /* optFlags already applied */);
2988 break;
buzbee4f1181f2012-06-22 13:52:12 -07002989 case greenland::IntrinsicHelper::HLInvokeObj:
buzbee8fa0fda2012-06-27 15:44:52 -07002990 case greenland::IntrinsicHelper::HLInvokeFloat:
2991 case greenland::IntrinsicHelper::HLInvokeDouble:
2992 case greenland::IntrinsicHelper::HLInvokeLong:
2993 case greenland::IntrinsicHelper::HLInvokeInt:
buzbee101305f2012-06-28 18:00:56 -07002994 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
buzbee4f1181f2012-06-22 13:52:12 -07002995 break;
buzbee6969d502012-06-15 16:40:31 -07002996 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbee101305f2012-06-28 18:00:56 -07002997 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
2998 break;
2999 case greenland::IntrinsicHelper::FilledNewArray:
3000 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
3001 break;
3002 case greenland::IntrinsicHelper::FillArrayData:
3003 cvtFillArrayData(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07003004 break;
3005 case greenland::IntrinsicHelper::ConstString:
buzbee101305f2012-06-28 18:00:56 -07003006 cvtConstObject(cUnit, callInst, true /* isString */);
3007 break;
3008 case greenland::IntrinsicHelper::ConstClass:
3009 cvtConstObject(cUnit, callInst, false /* isString */);
3010 break;
3011 case greenland::IntrinsicHelper::CheckCast:
3012 cvtCheckCast(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07003013 break;
buzbee4f1181f2012-06-22 13:52:12 -07003014 case greenland::IntrinsicHelper::NewInstance:
3015 cvtNewInstance(cUnit, callInst);
3016 break;
buzbee8fa0fda2012-06-27 15:44:52 -07003017 case greenland::IntrinsicHelper::HLSgetObject:
buzbee4f1181f2012-06-22 13:52:12 -07003018 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
3019 break;
buzbee8fa0fda2012-06-27 15:44:52 -07003020 case greenland::IntrinsicHelper::HLSget:
3021 case greenland::IntrinsicHelper::HLSgetFloat:
3022 case greenland::IntrinsicHelper::HLSgetBoolean:
3023 case greenland::IntrinsicHelper::HLSgetByte:
3024 case greenland::IntrinsicHelper::HLSgetChar:
3025 case greenland::IntrinsicHelper::HLSgetShort:
3026 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
3027 break;
3028 case greenland::IntrinsicHelper::HLSgetWide:
3029 case greenland::IntrinsicHelper::HLSgetDouble:
3030 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
3031 break;
buzbee76592632012-06-29 15:18:35 -07003032 case greenland::IntrinsicHelper::HLSput:
3033 case greenland::IntrinsicHelper::HLSputFloat:
3034 case greenland::IntrinsicHelper::HLSputBoolean:
3035 case greenland::IntrinsicHelper::HLSputByte:
3036 case greenland::IntrinsicHelper::HLSputChar:
3037 case greenland::IntrinsicHelper::HLSputShort:
3038 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
3039 break;
3040 case greenland::IntrinsicHelper::HLSputWide:
3041 case greenland::IntrinsicHelper::HLSputDouble:
3042 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
3043 break;
buzbeea1da8a52012-07-09 14:00:21 -07003044 case greenland::IntrinsicHelper::HLSputObject:
3045 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
3046 break;
buzbee32412962012-06-26 16:27:56 -07003047 case greenland::IntrinsicHelper::GetException:
3048 cvtMoveException(cUnit, callInst);
3049 break;
3050 case greenland::IntrinsicHelper::Throw:
3051 cvtThrow(cUnit, callInst);
3052 break;
3053 case greenland::IntrinsicHelper::ThrowVerificationError:
buzbee8fa0fda2012-06-27 15:44:52 -07003054 cvtThrowVerificationError(cUnit, callInst);
buzbee32412962012-06-26 16:27:56 -07003055 break;
buzbee8fa0fda2012-06-27 15:44:52 -07003056 case greenland::IntrinsicHelper::MonitorEnter:
3057 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
3058 break;
3059 case greenland::IntrinsicHelper::MonitorExit:
3060 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
3061 break;
3062 case greenland::IntrinsicHelper::ArrayLength:
buzbee76592632012-06-29 15:18:35 -07003063 cvtArrayLength(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07003064 break;
3065 case greenland::IntrinsicHelper::NewArray:
3066 cvtNewArray(cUnit, callInst);
3067 break;
3068 case greenland::IntrinsicHelper::InstanceOf:
3069 cvtInstanceOf(cUnit, callInst);
3070 break;
3071
3072 case greenland::IntrinsicHelper::HLArrayGet:
3073 case greenland::IntrinsicHelper::HLArrayGetObject:
3074 case greenland::IntrinsicHelper::HLArrayGetFloat:
3075 cvtAget(cUnit, callInst, kWord, 2);
3076 break;
3077 case greenland::IntrinsicHelper::HLArrayGetWide:
3078 case greenland::IntrinsicHelper::HLArrayGetDouble:
3079 cvtAget(cUnit, callInst, kLong, 3);
3080 break;
3081 case greenland::IntrinsicHelper::HLArrayGetBoolean:
3082 cvtAget(cUnit, callInst, kUnsignedByte, 0);
3083 break;
3084 case greenland::IntrinsicHelper::HLArrayGetByte:
3085 cvtAget(cUnit, callInst, kSignedByte, 0);
3086 break;
3087 case greenland::IntrinsicHelper::HLArrayGetChar:
3088 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
3089 break;
3090 case greenland::IntrinsicHelper::HLArrayGetShort:
3091 cvtAget(cUnit, callInst, kSignedHalf, 1);
3092 break;
3093
3094 case greenland::IntrinsicHelper::HLArrayPut:
buzbee8fa0fda2012-06-27 15:44:52 -07003095 case greenland::IntrinsicHelper::HLArrayPutFloat:
buzbeef1f86362012-07-10 15:18:31 -07003096 cvtAputPrimitive(cUnit, callInst, kWord, 2);
3097 break;
3098 case greenland::IntrinsicHelper::HLArrayPutObject:
3099 cvtAputObj(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07003100 break;
3101 case greenland::IntrinsicHelper::HLArrayPutWide:
3102 case greenland::IntrinsicHelper::HLArrayPutDouble:
buzbeef1f86362012-07-10 15:18:31 -07003103 cvtAputPrimitive(cUnit, callInst, kLong, 3);
buzbee8fa0fda2012-06-27 15:44:52 -07003104 break;
3105 case greenland::IntrinsicHelper::HLArrayPutBoolean:
buzbeef1f86362012-07-10 15:18:31 -07003106 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
buzbee8fa0fda2012-06-27 15:44:52 -07003107 break;
3108 case greenland::IntrinsicHelper::HLArrayPutByte:
buzbeef1f86362012-07-10 15:18:31 -07003109 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
buzbee8fa0fda2012-06-27 15:44:52 -07003110 break;
3111 case greenland::IntrinsicHelper::HLArrayPutChar:
buzbeef1f86362012-07-10 15:18:31 -07003112 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
buzbee8fa0fda2012-06-27 15:44:52 -07003113 break;
3114 case greenland::IntrinsicHelper::HLArrayPutShort:
buzbeef1f86362012-07-10 15:18:31 -07003115 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
buzbee8fa0fda2012-06-27 15:44:52 -07003116 break;
3117
buzbee101305f2012-06-28 18:00:56 -07003118 case greenland::IntrinsicHelper::HLIGet:
3119 case greenland::IntrinsicHelper::HLIGetFloat:
3120 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3121 break;
3122 case greenland::IntrinsicHelper::HLIGetObject:
3123 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3124 break;
3125 case greenland::IntrinsicHelper::HLIGetWide:
3126 case greenland::IntrinsicHelper::HLIGetDouble:
3127 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3128 break;
3129 case greenland::IntrinsicHelper::HLIGetBoolean:
3130 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3131 false /* obj */);
3132 break;
3133 case greenland::IntrinsicHelper::HLIGetByte:
3134 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3135 false /* obj */);
3136 break;
3137 case greenland::IntrinsicHelper::HLIGetChar:
3138 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3139 false /* obj */);
3140 break;
3141 case greenland::IntrinsicHelper::HLIGetShort:
3142 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3143 false /* obj */);
3144 break;
3145
3146 case greenland::IntrinsicHelper::HLIPut:
3147 case greenland::IntrinsicHelper::HLIPutFloat:
3148 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3149 break;
3150 case greenland::IntrinsicHelper::HLIPutObject:
3151 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3152 break;
3153 case greenland::IntrinsicHelper::HLIPutWide:
3154 case greenland::IntrinsicHelper::HLIPutDouble:
3155 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3156 break;
3157 case greenland::IntrinsicHelper::HLIPutBoolean:
3158 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3159 false /* obj */);
3160 break;
3161 case greenland::IntrinsicHelper::HLIPutByte:
3162 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3163 false /* obj */);
3164 break;
3165 case greenland::IntrinsicHelper::HLIPutChar:
3166 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3167 false /* obj */);
3168 break;
3169 case greenland::IntrinsicHelper::HLIPutShort:
3170 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3171 false /* obj */);
3172 break;
3173
3174 case greenland::IntrinsicHelper::IntToChar:
3175 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3176 break;
3177 case greenland::IntrinsicHelper::IntToShort:
3178 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3179 break;
3180 case greenland::IntrinsicHelper::IntToByte:
3181 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3182 break;
3183
buzbee76592632012-06-29 15:18:35 -07003184 case greenland::IntrinsicHelper::CmplFloat:
3185 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3186 break;
3187 case greenland::IntrinsicHelper::CmpgFloat:
3188 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3189 break;
3190 case greenland::IntrinsicHelper::CmplDouble:
3191 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3192 break;
3193 case greenland::IntrinsicHelper::CmpgDouble:
3194 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3195 break;
3196
3197 case greenland::IntrinsicHelper::CmpLong:
3198 cvtLongCompare(cUnit, callInst);
3199 break;
3200
buzbee2a83e8f2012-07-13 16:42:30 -07003201 case greenland::IntrinsicHelper::SHLLong:
3202 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
buzbee2cfc6392012-05-07 14:51:40 -07003203 break;
buzbee2a83e8f2012-07-13 16:42:30 -07003204 case greenland::IntrinsicHelper::SHRLong:
3205 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3206 break;
3207 case greenland::IntrinsicHelper::USHRLong:
3208 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3209 break;
3210 case greenland::IntrinsicHelper::SHLInt:
3211 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3212 break;
3213 case greenland::IntrinsicHelper::SHRInt:
3214 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3215 break;
3216 case greenland::IntrinsicHelper::USHRInt:
3217 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3218 break;
3219
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07003220 case greenland::IntrinsicHelper::CatchTargets: {
3221 llvm::SwitchInst* swInst =
3222 llvm::dyn_cast<llvm::SwitchInst>(nextIt);
3223 DCHECK(swInst != NULL);
3224 /*
3225 * Discard the edges and the following conditional branch.
3226 * Do a direct branch to the default target (which is the
3227 * "work" portion of the pair.
3228 * TODO: awful code layout - rework
3229 */
3230 llvm::BasicBlock* targetBB = swInst->getDefaultDest();
3231 DCHECK(targetBB != NULL);
3232 opUnconditionalBranch(cUnit,
3233 cUnit->blockToLabelMap.Get(targetBB));
3234 ++it;
3235 }
3236 break;
3237
buzbee2cfc6392012-05-07 14:51:40 -07003238 default:
3239 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3240 << cUnit->intrinsic_helper->GetName(id);
3241 }
3242 }
3243 break;
3244
3245 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3246 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3247 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3248 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3249 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3250 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3251 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3252 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3253 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003254 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3255 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
buzbee4f1181f2012-06-22 13:52:12 -07003256 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3257 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3258 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3259 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3260 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
buzbee76592632012-06-29 15:18:35 -07003261 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
3262 case llvm::Instruction::FPToSI: cvtFPToInt(cUnit, inst); break;
3263 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3264 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3265 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003266
buzbee101305f2012-06-28 18:00:56 -07003267 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3268 break;
3269 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3270 break;
3271
buzbeef58c12c2012-07-03 15:06:29 -07003272 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3273
buzbee32412962012-06-26 16:27:56 -07003274 case llvm::Instruction::Unreachable:
3275 break; // FIXME: can we really ignore these?
3276
buzbee2a83e8f2012-07-13 16:42:30 -07003277 case llvm::Instruction::Shl:
3278 case llvm::Instruction::LShr:
3279 case llvm::Instruction::AShr:
buzbee2cfc6392012-05-07 14:51:40 -07003280 case llvm::Instruction::Invoke:
buzbee2cfc6392012-05-07 14:51:40 -07003281 case llvm::Instruction::FPToUI:
buzbee2cfc6392012-05-07 14:51:40 -07003282 case llvm::Instruction::UIToFP:
buzbee2cfc6392012-05-07 14:51:40 -07003283 case llvm::Instruction::PtrToInt:
3284 case llvm::Instruction::IntToPtr:
buzbee2cfc6392012-05-07 14:51:40 -07003285 case llvm::Instruction::FCmp:
buzbee2cfc6392012-05-07 14:51:40 -07003286 case llvm::Instruction::URem:
3287 case llvm::Instruction::UDiv:
3288 case llvm::Instruction::Resume:
buzbee2cfc6392012-05-07 14:51:40 -07003289 case llvm::Instruction::Alloca:
3290 case llvm::Instruction::GetElementPtr:
3291 case llvm::Instruction::Fence:
3292 case llvm::Instruction::AtomicCmpXchg:
3293 case llvm::Instruction::AtomicRMW:
3294 case llvm::Instruction::BitCast:
3295 case llvm::Instruction::VAArg:
3296 case llvm::Instruction::Select:
3297 case llvm::Instruction::UserOp1:
3298 case llvm::Instruction::UserOp2:
3299 case llvm::Instruction::ExtractElement:
3300 case llvm::Instruction::InsertElement:
3301 case llvm::Instruction::ShuffleVector:
3302 case llvm::Instruction::ExtractValue:
3303 case llvm::Instruction::InsertValue:
3304 case llvm::Instruction::LandingPad:
3305 case llvm::Instruction::IndirectBr:
3306 case llvm::Instruction::Load:
3307 case llvm::Instruction::Store:
3308 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3309
3310 default:
buzbee2a83e8f2012-07-13 16:42:30 -07003311 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3312 break;
buzbee2cfc6392012-05-07 14:51:40 -07003313 }
3314 }
buzbee6969d502012-06-15 16:40:31 -07003315
3316 if (headLIR != NULL) {
3317 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
3318 }
buzbee2cfc6392012-05-07 14:51:40 -07003319 return false;
3320}
3321
3322/*
3323 * Convert LLVM_IR to MIR:
3324 * o Iterate through the LLVM_IR and construct a graph using
3325 * standard MIR building blocks.
3326 * o Perform a basic-block optimization pass to remove unnecessary
3327 * store/load sequences.
3328 * o Convert the LLVM Value operands into RegLocations where applicable.
3329 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3330 * o Perform register promotion
3331 * o Iterate through the graph a basic block at a time, generating
3332 * LIR.
3333 * o Assemble LIR as usual.
3334 * o Profit.
3335 */
3336void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3337{
buzbeead8f15e2012-06-18 14:49:45 -07003338 llvm::Function* func = cUnit->func;
3339 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003340 // Allocate a list for LIR basic block labels
3341 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07003342 (LIR*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3343 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003344 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003345 for (llvm::Function::iterator i = func->begin(),
3346 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003347 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3348 &labelList[nextLabel++]);
3349 }
buzbeead8f15e2012-06-18 14:49:45 -07003350
3351 /*
3352 * Keep honest - clear regLocations, Value => RegLocation,
3353 * promotion map and VmapTables.
3354 */
3355 cUnit->locMap.clear(); // Start fresh
3356 cUnit->regLocation = NULL;
3357 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3358 i++) {
3359 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3360 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3361 }
3362 cUnit->coreSpillMask = 0;
3363 cUnit->numCoreSpills = 0;
3364 cUnit->fpSpillMask = 0;
3365 cUnit->numFPSpills = 0;
3366 cUnit->coreVmapTable.clear();
3367 cUnit->fpVmapTable.clear();
3368 oatAdjustSpillMask(cUnit);
3369 cUnit->frameSize = oatComputeFrameSize(cUnit);
3370
3371 /*
3372 * At this point, we've lost all knowledge of register promotion.
3373 * Rebuild that info from the MethodInfo intrinsic (if it
3374 * exists - not required for correctness).
3375 */
3376 // TODO: find and recover MethodInfo.
3377
3378 // Create RegLocations for arguments
3379 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3380 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3381 for (; it != it_end; ++it) {
3382 llvm::Value* val = it;
3383 createLocFromValue(cUnit, val);
3384 }
3385 // Create RegLocations for all non-argument defintions
3386 for (llvm::inst_iterator i = llvm::inst_begin(func),
3387 e = llvm::inst_end(func); i != e; ++i) {
3388 llvm::Value* val = &*i;
3389 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3390 createLocFromValue(cUnit, val);
3391 }
3392 }
3393
buzbee2cfc6392012-05-07 14:51:40 -07003394 // Walk the blocks, generating code.
3395 for (llvm::Function::iterator i = cUnit->func->begin(),
3396 e = cUnit->func->end(); i != e; ++i) {
3397 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3398 }
3399
3400 handleSuspendLaunchpads(cUnit);
3401
3402 handleThrowLaunchpads(cUnit);
3403
3404 handleIntrinsicLaunchpads(cUnit);
3405
3406 freeIR(cUnit);
3407}
3408
3409
3410} // namespace art
3411
3412#endif // ART_USE_QUICK_COMPILER