blob: a8da1cde44a102e5def9da32de2baea068856fd2 [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
Brian Carlstrom937b73e2012-08-01 16:09:16 -070054 LOG(WARNING) << "Null placeholder - invalid CFG";
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);
Brian Carlstrom937b73e2012-08-01 16:09:16 -0700310 cUnit->irb->CreateUnreachable();
buzbee32412962012-06-26 16:27:56 -0700311}
312
buzbee8fa0fda2012-06-27 15:44:52 -0700313void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
314 greenland::IntrinsicHelper::IntrinsicId id,
315 RegLocation rlSrc)
316{
317 llvm::SmallVector<llvm::Value*, 2> args;
318 args.push_back(cUnit->irb->getInt32(optFlags));
319 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
320 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
321 cUnit->irb->CreateCall(func, args);
322}
323
buzbee76592632012-06-29 15:18:35 -0700324void convertArrayLength(CompilationUnit* cUnit, int optFlags,
325 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700326{
327 llvm::SmallVector<llvm::Value*, 2> args;
328 args.push_back(cUnit->irb->getInt32(optFlags));
329 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
330 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
331 greenland::IntrinsicHelper::ArrayLength);
buzbee76592632012-06-29 15:18:35 -0700332 llvm::Value* res = cUnit->irb->CreateCall(func, args);
333 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700334}
335
buzbee32412962012-06-26 16:27:56 -0700336void convertThrowVerificationError(CompilationUnit* cUnit, int info1, int info2)
337{
338 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
buzbeea1da8a52012-07-09 14:00:21 -0700339 greenland::IntrinsicHelper::ThrowVerificationError);
buzbee32412962012-06-26 16:27:56 -0700340 llvm::SmallVector<llvm::Value*, 2> args;
341 args.push_back(cUnit->irb->getInt32(info1));
342 args.push_back(cUnit->irb->getInt32(info2));
343 cUnit->irb->CreateCall(func, args);
buzbee32412962012-06-26 16:27:56 -0700344}
345
buzbee2cfc6392012-05-07 14:51:40 -0700346void emitSuspendCheck(CompilationUnit* cUnit)
347{
348 greenland::IntrinsicHelper::IntrinsicId id =
349 greenland::IntrinsicHelper::CheckSuspend;
350 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
351 cUnit->irb->CreateCall(intr);
352}
353
354llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
355 llvm::Value* src1, llvm::Value* src2)
356{
357 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700358 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700359 switch(cc) {
360 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
361 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
362 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
363 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
364 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
365 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
366 default: LOG(FATAL) << "Unexpected cc value " << cc;
367 }
368 return res;
369}
370
371void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
372 ConditionCode cc, RegLocation rlSrc1,
373 RegLocation rlSrc2)
374{
375 if (bb->taken->startOffset <= mir->offset) {
376 emitSuspendCheck(cUnit);
377 }
378 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
379 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
380 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
381 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
382 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
383 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700384 // Don't redo the fallthrough branch in the BB driver
385 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700386}
387
388void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
389 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
390{
391 if (bb->taken->startOffset <= mir->offset) {
392 emitSuspendCheck(cUnit);
393 }
394 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
395 llvm::Value* src2;
396 if (rlSrc1.ref) {
397 src2 = cUnit->irb->GetJNull();
398 } else {
399 src2 = cUnit->irb->getInt32(0);
400 }
401 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700402 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
403 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700404 // Don't redo the fallthrough branch in the BB driver
405 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700406}
407
408llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
409 llvm::Value* src1, llvm::Value* src2)
410{
411 greenland::IntrinsicHelper::IntrinsicId id;
412 if (isLong) {
413 if (isDiv) {
414 id = greenland::IntrinsicHelper::DivLong;
415 } else {
416 id = greenland::IntrinsicHelper::RemLong;
417 }
418 } else if (isDiv) {
419 id = greenland::IntrinsicHelper::DivInt;
420 } else {
421 id = greenland::IntrinsicHelper::RemInt;
422 }
423 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
424 llvm::SmallVector<llvm::Value*, 2>args;
425 args.push_back(src1);
426 args.push_back(src2);
427 return cUnit->irb->CreateCall(intr, args);
428}
429
430llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
431 llvm::Value* src1, llvm::Value* src2)
432{
433 llvm::Value* res = NULL;
434 switch(op) {
435 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
436 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700437 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700438 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
439 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
440 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
441 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
442 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
443 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700444 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
445 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
446 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700447 default:
448 LOG(FATAL) << "Invalid op " << op;
449 }
450 return res;
451}
452
453void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
454 RegLocation rlSrc1, RegLocation rlSrc2)
455{
456 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
457 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
458 llvm::Value* res = NULL;
459 switch(op) {
460 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
461 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
462 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
463 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
464 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
465 default:
466 LOG(FATAL) << "Invalid op " << op;
467 }
468 defineValue(cUnit, res, rlDest.origSReg);
469}
470
buzbee2a83e8f2012-07-13 16:42:30 -0700471void convertShift(CompilationUnit* cUnit,
472 greenland::IntrinsicHelper::IntrinsicId id,
473 RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
buzbee4f1181f2012-06-22 13:52:12 -0700474{
buzbee2a83e8f2012-07-13 16:42:30 -0700475 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
476 llvm::SmallVector<llvm::Value*, 2>args;
477 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
478 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
479 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
480 defineValue(cUnit, res, rlDest.origSReg);
481}
482
483void convertShiftLit(CompilationUnit* cUnit,
484 greenland::IntrinsicHelper::IntrinsicId id,
485 RegLocation rlDest, RegLocation rlSrc, int shiftAmount)
486{
487 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
488 llvm::SmallVector<llvm::Value*, 2>args;
489 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
490 args.push_back(cUnit->irb->getInt32(shiftAmount));
491 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700492 defineValue(cUnit, res, rlDest.origSReg);
493}
494
buzbee2cfc6392012-05-07 14:51:40 -0700495void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
496 RegLocation rlSrc1, RegLocation rlSrc2)
497{
498 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
499 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700500 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700501 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
502 defineValue(cUnit, res, rlDest.origSReg);
503}
504
buzbeeb03f4872012-06-11 15:22:11 -0700505void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
506{
507 int index = -1;
508 DCHECK(newVal != NULL);
509 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
510 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
511 if (cUnit->shadowMap[i] == vReg) {
512 index = i;
513 break;
514 }
515 }
Elliott Hughes74847412012-06-20 18:10:21 -0700516 DCHECK_NE(index, -1) << "Corrupt shadowMap";
buzbeeb03f4872012-06-11 15:22:11 -0700517 greenland::IntrinsicHelper::IntrinsicId id =
518 greenland::IntrinsicHelper::SetShadowFrameEntry;
519 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
520 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
521 llvm::Value* args[] = { newVal, tableSlot };
522 cUnit->irb->CreateCall(func, args);
523}
524
buzbee2cfc6392012-05-07 14:51:40 -0700525void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
526 RegLocation rlSrc1, int32_t imm)
527{
528 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
529 llvm::Value* src2 = cUnit->irb->getInt32(imm);
530 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
531 defineValue(cUnit, res, rlDest.origSReg);
532}
533
buzbee101305f2012-06-28 18:00:56 -0700534/*
535 * Process arguments for invoke. Note: this code is also used to
536 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
537 * The requirements are similar.
538 */
buzbee6969d502012-06-15 16:40:31 -0700539void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700540 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700541{
542 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
543 llvm::SmallVector<llvm::Value*, 10> args;
544 // Insert the invokeType
545 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
546 // Insert the method_idx
547 args.push_back(cUnit->irb->getInt32(info->index));
548 // Insert the optimization flags
549 args.push_back(cUnit->irb->getInt32(info->optFlags));
550 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700551 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700552 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
553 args.push_back(val);
554 i += info->args[i].wide ? 2 : 1;
555 }
556 /*
557 * Choose the invoke return type based on actual usage. Note: may
558 * be different than shorty. For example, if a function return value
559 * is not used, we'll treat this as a void invoke.
560 */
561 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700562 if (isFilledNewArray) {
563 id = greenland::IntrinsicHelper::FilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700564 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700565 id = greenland::IntrinsicHelper::HLInvokeVoid;
566 } else {
567 if (info->result.wide) {
568 if (info->result.fp) {
569 id = greenland::IntrinsicHelper::HLInvokeDouble;
570 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700571 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700572 }
573 } else if (info->result.ref) {
574 id = greenland::IntrinsicHelper::HLInvokeObj;
575 } else if (info->result.fp) {
576 id = greenland::IntrinsicHelper::HLInvokeFloat;
577 } else {
578 id = greenland::IntrinsicHelper::HLInvokeInt;
579 }
580 }
581 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
582 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
583 if (info->result.location != kLocInvalid) {
584 defineValue(cUnit, res, info->result.origSReg);
585 }
586}
587
buzbee101305f2012-06-28 18:00:56 -0700588void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
589 greenland::IntrinsicHelper::IntrinsicId id,
590 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700591{
buzbee6969d502012-06-15 16:40:31 -0700592 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700593 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700594 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
595 defineValue(cUnit, res, rlDest.origSReg);
596}
597
buzbee101305f2012-06-28 18:00:56 -0700598void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
599 RegLocation rlSrc)
600{
601 greenland::IntrinsicHelper::IntrinsicId id;
602 id = greenland::IntrinsicHelper::CheckCast;
603 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
604 llvm::SmallVector<llvm::Value*, 2> args;
605 args.push_back(cUnit->irb->getInt32(type_idx));
606 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
607 cUnit->irb->CreateCall(intr, args);
608}
609
buzbee8fa0fda2012-06-27 15:44:52 -0700610void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
611 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700612{
613 greenland::IntrinsicHelper::IntrinsicId id;
614 id = greenland::IntrinsicHelper::NewInstance;
615 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
616 llvm::Value* index = cUnit->irb->getInt32(type_idx);
617 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
618 defineValue(cUnit, res, rlDest.origSReg);
619}
620
buzbee8fa0fda2012-06-27 15:44:52 -0700621void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
622 RegLocation rlDest, RegLocation rlSrc)
623{
624 greenland::IntrinsicHelper::IntrinsicId id;
625 id = greenland::IntrinsicHelper::NewArray;
626 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
627 llvm::SmallVector<llvm::Value*, 2> args;
628 args.push_back(cUnit->irb->getInt32(type_idx));
629 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
630 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
631 defineValue(cUnit, res, rlDest.origSReg);
632}
633
634void convertAget(CompilationUnit* cUnit, int optFlags,
635 greenland::IntrinsicHelper::IntrinsicId id,
636 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
637{
638 llvm::SmallVector<llvm::Value*, 3> args;
639 args.push_back(cUnit->irb->getInt32(optFlags));
640 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
641 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
642 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
643 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
644 defineValue(cUnit, res, rlDest.origSReg);
645}
646
647void convertAput(CompilationUnit* cUnit, int optFlags,
648 greenland::IntrinsicHelper::IntrinsicId id,
649 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
650{
651 llvm::SmallVector<llvm::Value*, 4> args;
652 args.push_back(cUnit->irb->getInt32(optFlags));
653 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
654 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
655 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
656 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
657 cUnit->irb->CreateCall(intr, args);
658}
659
buzbee101305f2012-06-28 18:00:56 -0700660void convertIget(CompilationUnit* cUnit, int optFlags,
661 greenland::IntrinsicHelper::IntrinsicId id,
662 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
663{
664 llvm::SmallVector<llvm::Value*, 3> args;
665 args.push_back(cUnit->irb->getInt32(optFlags));
666 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
667 args.push_back(cUnit->irb->getInt32(fieldIndex));
668 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
669 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
670 defineValue(cUnit, res, rlDest.origSReg);
671}
672
673void convertIput(CompilationUnit* cUnit, int optFlags,
674 greenland::IntrinsicHelper::IntrinsicId id,
675 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
676{
677 llvm::SmallVector<llvm::Value*, 4> args;
678 args.push_back(cUnit->irb->getInt32(optFlags));
679 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
680 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
681 args.push_back(cUnit->irb->getInt32(fieldIndex));
682 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
683 cUnit->irb->CreateCall(intr, args);
684}
685
buzbee8fa0fda2012-06-27 15:44:52 -0700686void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
687 RegLocation rlDest, RegLocation rlSrc)
688{
689 greenland::IntrinsicHelper::IntrinsicId id;
690 id = greenland::IntrinsicHelper::InstanceOf;
691 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
692 llvm::SmallVector<llvm::Value*, 2> args;
693 args.push_back(cUnit->irb->getInt32(type_idx));
694 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
695 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
696 defineValue(cUnit, res, rlDest.origSReg);
697}
698
buzbee101305f2012-06-28 18:00:56 -0700699void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
700 RegLocation rlSrc)
701{
702 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
703 cUnit->irb->getInt64Ty());
704 defineValue(cUnit, res, rlDest.origSReg);
705}
706
buzbee76592632012-06-29 15:18:35 -0700707void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
708 RegLocation rlSrc)
709{
710 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
711 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
712 defineValue(cUnit, res, rlDest.origSReg);
713}
714
715void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
716 RegLocation rlSrc)
717{
718 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
719 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
720 defineValue(cUnit, res, rlDest.origSReg);
721}
722
723void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
724 RegLocation rlSrc)
725{
726 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
727 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
728 defineValue(cUnit, res, rlDest.origSReg);
729}
730
731void convertWideComparison(CompilationUnit* cUnit,
732 greenland::IntrinsicHelper::IntrinsicId id,
733 RegLocation rlDest, RegLocation rlSrc1,
734 RegLocation rlSrc2)
735{
736 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
737 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
738 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
739 llvm::SmallVector<llvm::Value*, 2> args;
740 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
741 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
742 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
743 defineValue(cUnit, res, rlDest.origSReg);
744}
745
buzbee101305f2012-06-28 18:00:56 -0700746void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
747 RegLocation rlSrc,
748 greenland::IntrinsicHelper::IntrinsicId id)
749{
750 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700751 llvm::Value* res =
752 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
753 defineValue(cUnit, res, rlDest.origSReg);
754}
755
756void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
757 RegLocation rlSrc)
758{
759 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
760 defineValue(cUnit, res, rlDest.origSReg);
761}
762
763void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
764 RegLocation rlSrc)
765{
766 llvm::Value* res =
767 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
768 defineValue(cUnit, res, rlDest.origSReg);
769}
770
771void convertFPToInt(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
772 RegLocation rlSrc)
773{
774 llvm::Value* res =
775 cUnit->irb->CreateFPToSI(getLLVMValue(cUnit, rlSrc.origSReg), ty);
776 defineValue(cUnit, res, rlDest.origSReg);
777}
778
779
780void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
781 RegLocation rlSrc)
782{
783 llvm::Value* res =
784 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
785 defineValue(cUnit, res, rlDest.origSReg);
786}
787
788void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
789 RegLocation rlSrc)
790{
791 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
792 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700793 defineValue(cUnit, res, rlDest.origSReg);
794}
795
buzbee2cfc6392012-05-07 14:51:40 -0700796/*
797 * Target-independent code generation. Use only high-level
798 * load/store utilities here, or target-dependent genXX() handlers
799 * when necessary.
800 */
801bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
802 llvm::BasicBlock* llvmBB, LIR* labelList)
803{
804 bool res = false; // Assume success
805 RegLocation rlSrc[3];
806 RegLocation rlDest = badLoc;
buzbee2cfc6392012-05-07 14:51:40 -0700807 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee32412962012-06-26 16:27:56 -0700808 uint32_t vA = mir->dalvikInsn.vA;
buzbee6969d502012-06-15 16:40:31 -0700809 uint32_t vB = mir->dalvikInsn.vB;
810 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700811 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700812
buzbeeb03f4872012-06-11 15:22:11 -0700813 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700814
815 /* Prep Src and Dest locations */
816 int nextSreg = 0;
817 int nextLoc = 0;
818 int attrs = oatDataFlowAttributes[opcode];
819 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
820 if (attrs & DF_UA) {
821 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700822 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700823 nextSreg+= 2;
824 } else {
825 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
826 nextSreg++;
827 }
828 }
829 if (attrs & DF_UB) {
830 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700831 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700832 nextSreg+= 2;
833 } else {
834 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
835 nextSreg++;
836 }
837 }
838 if (attrs & DF_UC) {
839 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700840 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700841 } else {
842 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
843 }
844 }
845 if (attrs & DF_DA) {
846 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700847 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700848 } else {
buzbee15bf9802012-06-12 17:49:27 -0700849 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700850 if (rlDest.ref) {
851 objectDefinition = true;
852 }
buzbee2cfc6392012-05-07 14:51:40 -0700853 }
854 }
855
856 switch (opcode) {
857 case Instruction::NOP:
858 break;
859
860 case Instruction::MOVE:
861 case Instruction::MOVE_OBJECT:
862 case Instruction::MOVE_16:
863 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700864 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700865 case Instruction::MOVE_FROM16:
866 case Instruction::MOVE_WIDE:
867 case Instruction::MOVE_WIDE_16:
868 case Instruction::MOVE_WIDE_FROM16: {
869 /*
870 * Moves/copies are meaningless in pure SSA register form,
871 * but we need to preserve them for the conversion back into
872 * MIR (at least until we stop using the Dalvik register maps).
873 * Insert a dummy intrinsic copy call, which will be recognized
874 * by the quick path and removed by the portable path.
875 */
876 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
877 llvm::Value* res = emitCopy(cUnit, src, rlDest);
878 defineValue(cUnit, res, rlDest.origSReg);
879 }
880 break;
881
882 case Instruction::CONST:
883 case Instruction::CONST_4:
884 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700885 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700886 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
887 defineValue(cUnit, res, rlDest.origSReg);
888 }
889 break;
890
891 case Instruction::CONST_WIDE_16:
892 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700893 // Sign extend to 64 bits
894 int64_t imm = static_cast<int32_t>(vB);
895 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700896 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
897 defineValue(cUnit, res, rlDest.origSReg);
898 }
899 break;
900
901 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700902 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700903 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
904 defineValue(cUnit, res, rlDest.origSReg);
905 }
906 break;
907
908 case Instruction::CONST_WIDE: {
909 llvm::Constant* immValue =
910 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
911 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
912 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700913 }
914 break;
buzbee2cfc6392012-05-07 14:51:40 -0700915 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700916 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700917 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
918 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
919 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700920 }
921 break;
922
buzbee8fa0fda2012-06-27 15:44:52 -0700923 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700924 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700925 rlSrc[0]);
926 break;
927 case Instruction::SPUT:
928 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700929 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700930 rlSrc[0]);
931 } else {
buzbee76592632012-06-29 15:18:35 -0700932 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700933 }
934 break;
935 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700936 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700937 rlSrc[0]);
938 break;
939 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700940 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700941 break;
942 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700943 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700944 break;
945 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -0700946 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700947 break;
948 case Instruction::SPUT_WIDE:
949 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700950 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -0700951 rlSrc[0]);
952 } else {
buzbee76592632012-06-29 15:18:35 -0700953 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -0700954 rlSrc[0]);
955 }
956 break;
957
958 case Instruction::SGET_OBJECT:
959 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
960 break;
961 case Instruction::SGET:
962 if (rlDest.fp) {
963 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
964 } else {
965 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
966 }
967 break;
968 case Instruction::SGET_BOOLEAN:
969 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
970 break;
971 case Instruction::SGET_BYTE:
972 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
973 break;
974 case Instruction::SGET_CHAR:
975 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
976 break;
977 case Instruction::SGET_SHORT:
978 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
979 break;
980 case Instruction::SGET_WIDE:
981 if (rlDest.fp) {
982 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
983 rlDest);
984 } else {
985 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -0700986 }
987 break;
buzbee2cfc6392012-05-07 14:51:40 -0700988
989 case Instruction::RETURN_WIDE:
990 case Instruction::RETURN:
991 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -0700992 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700993 emitSuspendCheck(cUnit);
994 }
buzbeeb03f4872012-06-11 15:22:11 -0700995 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700996 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
997 bb->hasReturn = true;
998 }
999 break;
1000
1001 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001002 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001003 emitSuspendCheck(cUnit);
1004 }
buzbeeb03f4872012-06-11 15:22:11 -07001005 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001006 cUnit->irb->CreateRetVoid();
1007 bb->hasReturn = true;
1008 }
1009 break;
1010
1011 case Instruction::IF_EQ:
1012 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1013 break;
1014 case Instruction::IF_NE:
1015 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1016 break;
1017 case Instruction::IF_LT:
1018 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1019 break;
1020 case Instruction::IF_GE:
1021 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1022 break;
1023 case Instruction::IF_GT:
1024 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1025 break;
1026 case Instruction::IF_LE:
1027 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1028 break;
1029 case Instruction::IF_EQZ:
1030 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1031 break;
1032 case Instruction::IF_NEZ:
1033 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1034 break;
1035 case Instruction::IF_LTZ:
1036 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1037 break;
1038 case Instruction::IF_GEZ:
1039 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1040 break;
1041 case Instruction::IF_GTZ:
1042 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1043 break;
1044 case Instruction::IF_LEZ:
1045 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1046 break;
1047
1048 case Instruction::GOTO:
1049 case Instruction::GOTO_16:
1050 case Instruction::GOTO_32: {
1051 if (bb->taken->startOffset <= bb->startOffset) {
1052 emitSuspendCheck(cUnit);
1053 }
1054 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1055 }
1056 break;
1057
1058 case Instruction::ADD_LONG:
1059 case Instruction::ADD_LONG_2ADDR:
1060 case Instruction::ADD_INT:
1061 case Instruction::ADD_INT_2ADDR:
1062 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1063 break;
1064 case Instruction::SUB_LONG:
1065 case Instruction::SUB_LONG_2ADDR:
1066 case Instruction::SUB_INT:
1067 case Instruction::SUB_INT_2ADDR:
1068 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1069 break;
1070 case Instruction::MUL_LONG:
1071 case Instruction::MUL_LONG_2ADDR:
1072 case Instruction::MUL_INT:
1073 case Instruction::MUL_INT_2ADDR:
1074 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1075 break;
1076 case Instruction::DIV_LONG:
1077 case Instruction::DIV_LONG_2ADDR:
1078 case Instruction::DIV_INT:
1079 case Instruction::DIV_INT_2ADDR:
1080 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1081 break;
1082 case Instruction::REM_LONG:
1083 case Instruction::REM_LONG_2ADDR:
1084 case Instruction::REM_INT:
1085 case Instruction::REM_INT_2ADDR:
1086 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1087 break;
1088 case Instruction::AND_LONG:
1089 case Instruction::AND_LONG_2ADDR:
1090 case Instruction::AND_INT:
1091 case Instruction::AND_INT_2ADDR:
1092 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1093 break;
1094 case Instruction::OR_LONG:
1095 case Instruction::OR_LONG_2ADDR:
1096 case Instruction::OR_INT:
1097 case Instruction::OR_INT_2ADDR:
1098 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1099 break;
1100 case Instruction::XOR_LONG:
1101 case Instruction::XOR_LONG_2ADDR:
1102 case Instruction::XOR_INT:
1103 case Instruction::XOR_INT_2ADDR:
1104 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1105 break;
1106 case Instruction::SHL_LONG:
1107 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001108 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1109 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001110 break;
buzbee2cfc6392012-05-07 14:51:40 -07001111 case Instruction::SHL_INT:
1112 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001113 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1114 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001115 break;
1116 case Instruction::SHR_LONG:
1117 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001118 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1119 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001120 break;
buzbee2cfc6392012-05-07 14:51:40 -07001121 case Instruction::SHR_INT:
1122 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001123 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1124 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001125 break;
1126 case Instruction::USHR_LONG:
1127 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001128 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1129 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001130 break;
buzbee2cfc6392012-05-07 14:51:40 -07001131 case Instruction::USHR_INT:
1132 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001133 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1134 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001135 break;
1136
1137 case Instruction::ADD_INT_LIT16:
1138 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001139 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001140 break;
1141 case Instruction::RSUB_INT:
1142 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001143 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001144 break;
1145 case Instruction::MUL_INT_LIT16:
1146 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001147 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001148 break;
1149 case Instruction::DIV_INT_LIT16:
1150 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001151 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001152 break;
1153 case Instruction::REM_INT_LIT16:
1154 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001155 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001156 break;
1157 case Instruction::AND_INT_LIT16:
1158 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001159 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001160 break;
1161 case Instruction::OR_INT_LIT16:
1162 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001163 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001164 break;
1165 case Instruction::XOR_INT_LIT16:
1166 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001167 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001168 break;
1169 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001170 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1171 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001172 break;
1173 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001174 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1175 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001176 break;
1177 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001178 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1179 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001180 break;
1181
1182 case Instruction::ADD_FLOAT:
1183 case Instruction::ADD_FLOAT_2ADDR:
1184 case Instruction::ADD_DOUBLE:
1185 case Instruction::ADD_DOUBLE_2ADDR:
1186 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1187 break;
1188
1189 case Instruction::SUB_FLOAT:
1190 case Instruction::SUB_FLOAT_2ADDR:
1191 case Instruction::SUB_DOUBLE:
1192 case Instruction::SUB_DOUBLE_2ADDR:
1193 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1194 break;
1195
1196 case Instruction::MUL_FLOAT:
1197 case Instruction::MUL_FLOAT_2ADDR:
1198 case Instruction::MUL_DOUBLE:
1199 case Instruction::MUL_DOUBLE_2ADDR:
1200 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1201 break;
1202
1203 case Instruction::DIV_FLOAT:
1204 case Instruction::DIV_FLOAT_2ADDR:
1205 case Instruction::DIV_DOUBLE:
1206 case Instruction::DIV_DOUBLE_2ADDR:
1207 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1208 break;
1209
1210 case Instruction::REM_FLOAT:
1211 case Instruction::REM_FLOAT_2ADDR:
1212 case Instruction::REM_DOUBLE:
1213 case Instruction::REM_DOUBLE_2ADDR:
1214 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1215 break;
1216
buzbee6969d502012-06-15 16:40:31 -07001217 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001218 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1219 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001220 break;
1221 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001222 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1223 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001224 break;
1225
1226 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001227 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1228 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001229 break;
1230 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001231 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1232 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001233 break;
1234
1235 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001236 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1237 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001238 break;
1239 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001240 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1241 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001242 break;
1243
1244 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001245 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1246 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001247 break;
1248 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001249 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1250 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001251 break;
1252
1253 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001254 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1255 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001256 break;
1257 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001258 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1259 false /* NewFilledArray */);
1260 break;
1261 case Instruction::FILLED_NEW_ARRAY:
1262 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1263 true /* NewFilledArray */);
1264 break;
1265 case Instruction::FILLED_NEW_ARRAY_RANGE:
1266 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1267 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001268 break;
1269
1270 case Instruction::CONST_STRING:
1271 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001272 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1273 rlDest);
1274 break;
1275
1276 case Instruction::CONST_CLASS:
1277 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1278 rlDest);
1279 break;
1280
1281 case Instruction::CHECK_CAST:
1282 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001283 break;
1284
buzbee4f1181f2012-06-22 13:52:12 -07001285 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001286 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001287 break;
1288
buzbee32412962012-06-26 16:27:56 -07001289 case Instruction::MOVE_EXCEPTION:
1290 convertMoveException(cUnit, rlDest);
1291 break;
1292
1293 case Instruction::THROW:
1294 convertThrow(cUnit, rlSrc[0]);
1295 break;
1296
1297 case Instruction::THROW_VERIFICATION_ERROR:
1298 convertThrowVerificationError(cUnit, vA, vB);
1299 break;
buzbee6969d502012-06-15 16:40:31 -07001300
buzbee2cfc6392012-05-07 14:51:40 -07001301 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001302 case Instruction::MOVE_RESULT:
1303 case Instruction::MOVE_RESULT_OBJECT:
buzbee85eee022012-07-16 22:12:38 -07001304#if defined(TARGET_ARM)
buzbee9a2487f2012-07-26 14:01:13 -07001305 /*
1306 * Instruction rewriting on verification failure can eliminate
1307 * the invoke that feeds this move0result. It won't ever be reached,
1308 * so we can ignore it.
Brian Carlstrom937b73e2012-08-01 16:09:16 -07001309 * TODO: verify that previous instruction if THROW_VERIFICATION_ERROR
buzbee9a2487f2012-07-26 14:01:13 -07001310 */
1311 UNIMPLEMENTED(WARNING) << "Need to verify previous inst was rewritten";
buzbee85eee022012-07-16 22:12:38 -07001312#else
1313 UNIMPLEMENTED(WARNING) << "need x86 move-result fusing";
1314#endif
1315
buzbee2cfc6392012-05-07 14:51:40 -07001316 break;
1317
1318 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001319 convertMonitorEnterExit(cUnit, optFlags,
1320 greenland::IntrinsicHelper::MonitorEnter,
1321 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001322 break;
1323
1324 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001325 convertMonitorEnterExit(cUnit, optFlags,
1326 greenland::IntrinsicHelper::MonitorExit,
1327 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001328 break;
1329
1330 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001331 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001332 break;
1333
1334 case Instruction::NEW_ARRAY:
1335 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1336 break;
1337
1338 case Instruction::INSTANCE_OF:
1339 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1340 break;
1341
1342 case Instruction::AGET:
1343 if (rlDest.fp) {
1344 convertAget(cUnit, optFlags,
1345 greenland::IntrinsicHelper::HLArrayGetFloat,
1346 rlDest, rlSrc[0], rlSrc[1]);
1347 } else {
1348 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1349 rlDest, rlSrc[0], rlSrc[1]);
1350 }
1351 break;
1352 case Instruction::AGET_OBJECT:
1353 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1354 rlDest, rlSrc[0], rlSrc[1]);
1355 break;
1356 case Instruction::AGET_BOOLEAN:
1357 convertAget(cUnit, optFlags,
1358 greenland::IntrinsicHelper::HLArrayGetBoolean,
1359 rlDest, rlSrc[0], rlSrc[1]);
1360 break;
1361 case Instruction::AGET_BYTE:
1362 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1363 rlDest, rlSrc[0], rlSrc[1]);
1364 break;
1365 case Instruction::AGET_CHAR:
1366 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1367 rlDest, rlSrc[0], rlSrc[1]);
1368 break;
1369 case Instruction::AGET_SHORT:
1370 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1371 rlDest, rlSrc[0], rlSrc[1]);
1372 break;
1373 case Instruction::AGET_WIDE:
1374 if (rlDest.fp) {
1375 convertAget(cUnit, optFlags,
1376 greenland::IntrinsicHelper::HLArrayGetDouble,
1377 rlDest, rlSrc[0], rlSrc[1]);
1378 } else {
1379 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1380 rlDest, rlSrc[0], rlSrc[1]);
1381 }
1382 break;
1383
1384 case Instruction::APUT:
1385 if (rlSrc[0].fp) {
1386 convertAput(cUnit, optFlags,
1387 greenland::IntrinsicHelper::HLArrayPutFloat,
1388 rlSrc[0], rlSrc[1], rlSrc[2]);
1389 } else {
1390 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1391 rlSrc[0], rlSrc[1], rlSrc[2]);
1392 }
1393 break;
1394 case Instruction::APUT_OBJECT:
1395 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1396 rlSrc[0], rlSrc[1], rlSrc[2]);
1397 break;
1398 case Instruction::APUT_BOOLEAN:
1399 convertAput(cUnit, optFlags,
1400 greenland::IntrinsicHelper::HLArrayPutBoolean,
1401 rlSrc[0], rlSrc[1], rlSrc[2]);
1402 break;
1403 case Instruction::APUT_BYTE:
1404 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1405 rlSrc[0], rlSrc[1], rlSrc[2]);
1406 break;
1407 case Instruction::APUT_CHAR:
1408 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1409 rlSrc[0], rlSrc[1], rlSrc[2]);
1410 break;
1411 case Instruction::APUT_SHORT:
1412 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1413 rlSrc[0], rlSrc[1], rlSrc[2]);
1414 break;
1415 case Instruction::APUT_WIDE:
1416 if (rlSrc[0].fp) {
1417 convertAput(cUnit, optFlags,
1418 greenland::IntrinsicHelper::HLArrayPutDouble,
1419 rlSrc[0], rlSrc[1], rlSrc[2]);
1420 } else {
1421 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1422 rlSrc[0], rlSrc[1], rlSrc[2]);
1423 }
1424 break;
1425
buzbee101305f2012-06-28 18:00:56 -07001426 case Instruction::IGET:
1427 if (rlDest.fp) {
1428 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001429 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001430 } else {
1431 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001432 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001433 }
buzbee2cfc6392012-05-07 14:51:40 -07001434 break;
buzbee101305f2012-06-28 18:00:56 -07001435 case Instruction::IGET_OBJECT:
1436 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001437 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001438 break;
1439 case Instruction::IGET_BOOLEAN:
1440 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001441 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001442 break;
1443 case Instruction::IGET_BYTE:
1444 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001445 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001446 break;
1447 case Instruction::IGET_CHAR:
1448 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001449 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001450 break;
1451 case Instruction::IGET_SHORT:
1452 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001453 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001454 break;
1455 case Instruction::IGET_WIDE:
1456 if (rlDest.fp) {
1457 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001458 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001459 } else {
1460 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001461 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001462 }
1463 break;
1464 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001465 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001466 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1467 rlSrc[0], rlSrc[1], vC);
1468 } else {
1469 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1470 rlSrc[0], rlSrc[1], vC);
1471 }
1472 break;
1473 case Instruction::IPUT_OBJECT:
1474 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1475 rlSrc[0], rlSrc[1], vC);
1476 break;
1477 case Instruction::IPUT_BOOLEAN:
1478 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1479 rlSrc[0], rlSrc[1], vC);
1480 break;
1481 case Instruction::IPUT_BYTE:
1482 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1483 rlSrc[0], rlSrc[1], vC);
1484 break;
1485 case Instruction::IPUT_CHAR:
1486 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1487 rlSrc[0], rlSrc[1], vC);
1488 break;
1489 case Instruction::IPUT_SHORT:
1490 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1491 rlSrc[0], rlSrc[1], vC);
1492 break;
1493 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001494 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001495 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1496 rlSrc[0], rlSrc[1], vC);
1497 } else {
1498 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1499 rlSrc[0], rlSrc[1], vC);
1500 }
buzbee2cfc6392012-05-07 14:51:40 -07001501 break;
1502
1503 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001504 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001505 break;
1506
buzbee76592632012-06-29 15:18:35 -07001507 case Instruction::LONG_TO_INT:
1508 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1509 break;
1510
buzbee101305f2012-06-28 18:00:56 -07001511 case Instruction::INT_TO_LONG:
1512 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001513 break;
1514
buzbee101305f2012-06-28 18:00:56 -07001515 case Instruction::INT_TO_CHAR:
1516 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1517 greenland::IntrinsicHelper::IntToChar);
1518 break;
1519 case Instruction::INT_TO_BYTE:
1520 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1521 greenland::IntrinsicHelper::IntToByte);
1522 break;
1523 case Instruction::INT_TO_SHORT:
1524 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1525 greenland::IntrinsicHelper::IntToShort);
1526 break;
1527
buzbee76592632012-06-29 15:18:35 -07001528 case Instruction::INT_TO_FLOAT:
1529 case Instruction::LONG_TO_FLOAT:
1530 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001531 break;
1532
buzbee76592632012-06-29 15:18:35 -07001533 case Instruction::INT_TO_DOUBLE:
1534 case Instruction::LONG_TO_DOUBLE:
1535 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001536 break;
1537
buzbee76592632012-06-29 15:18:35 -07001538 case Instruction::FLOAT_TO_DOUBLE:
1539 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001540 break;
1541
buzbee76592632012-06-29 15:18:35 -07001542 case Instruction::DOUBLE_TO_FLOAT:
1543 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001544 break;
1545
1546 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001547 case Instruction::NEG_INT:
1548 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001549 break;
1550
1551 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001552 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001553 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001554 break;
1555
buzbee76592632012-06-29 15:18:35 -07001556 case Instruction::NOT_LONG:
1557 case Instruction::NOT_INT:
1558 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001559 break;
1560
buzbee2cfc6392012-05-07 14:51:40 -07001561 case Instruction::FLOAT_TO_INT:
buzbee2cfc6392012-05-07 14:51:40 -07001562 case Instruction::DOUBLE_TO_INT:
buzbee76592632012-06-29 15:18:35 -07001563 convertFPToInt(cUnit, cUnit->irb->getInt32Ty(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001564 break;
1565
buzbee76592632012-06-29 15:18:35 -07001566 case Instruction::FLOAT_TO_LONG:
1567 case Instruction::DOUBLE_TO_LONG:
1568 convertFPToInt(cUnit, cUnit->irb->getInt64Ty(), rlDest, rlSrc[0]);
1569 break;
1570
1571 case Instruction::CMPL_FLOAT:
1572 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1573 rlDest, rlSrc[0], rlSrc[1]);
1574 break;
1575 case Instruction::CMPG_FLOAT:
1576 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1577 rlDest, rlSrc[0], rlSrc[1]);
1578 break;
1579 case Instruction::CMPL_DOUBLE:
1580 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1581 rlDest, rlSrc[0], rlSrc[1]);
1582 break;
1583 case Instruction::CMPG_DOUBLE:
1584 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1585 rlDest, rlSrc[0], rlSrc[1]);
1586 break;
1587 case Instruction::CMP_LONG:
1588 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1589 rlDest, rlSrc[0], rlSrc[1]);
1590 break;
1591
buzbee76592632012-06-29 15:18:35 -07001592 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001593 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001594 break;
1595
1596 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001597 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001598 break;
buzbee2cfc6392012-05-07 14:51:40 -07001599
1600 default:
buzbee32412962012-06-26 16:27:56 -07001601 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001602 res = true;
1603 }
buzbeeb03f4872012-06-11 15:22:11 -07001604 if (objectDefinition) {
1605 setShadowFrameEntry(cUnit, (llvm::Value*)
1606 cUnit->llvmValues.elemList[rlDest.origSReg]);
1607 }
buzbee2cfc6392012-05-07 14:51:40 -07001608 return res;
1609}
1610
1611/* Extended MIR instructions like PHI */
1612void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1613 llvm::BasicBlock* llvmBB)
1614{
1615
1616 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1617 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001618 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001619 /*
1620 * The Art compiler's Phi nodes only handle 32-bit operands,
1621 * representing wide values using a matched set of Phi nodes
1622 * for the lower and upper halves. In the llvm world, we only
1623 * want a single Phi for wides. Here we will simply discard
1624 * the Phi node representing the high word.
1625 */
1626 if (rlDest.highWord) {
1627 return; // No Phi node - handled via low word
1628 }
1629 int* incoming = (int*)mir->dalvikInsn.vB;
buzbee2cfc6392012-05-07 14:51:40 -07001630 llvm::Type* phiType =
1631 llvmTypeFromLocRec(cUnit, rlDest);
1632 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1633 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1634 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001635 // Don't check width here.
1636 loc = oatGetRawSrc(cUnit, mir, i);
1637 DCHECK_EQ(rlDest.wide, loc.wide);
1638 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1639 DCHECK_EQ(rlDest.fp, loc.fp);
1640 DCHECK_EQ(rlDest.core, loc.core);
1641 DCHECK_EQ(rlDest.ref, loc.ref);
buzbee2cfc6392012-05-07 14:51:40 -07001642 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
1643 getLLVMBlock(cUnit, incoming[i]));
1644 }
1645 defineValue(cUnit, phi, rlDest.origSReg);
1646 break;
1647 }
1648 case kMirOpCopy: {
1649 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1650 break;
1651 }
1652#if defined(TARGET_ARM)
1653 case kMirOpFusedCmplFloat:
1654 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1655 break;
1656 case kMirOpFusedCmpgFloat:
1657 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1658 break;
1659 case kMirOpFusedCmplDouble:
1660 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1661 break;
1662 case kMirOpFusedCmpgDouble:
1663 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1664 break;
1665 case kMirOpFusedCmpLong:
1666 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1667 break;
1668#endif
1669 default:
1670 break;
1671 }
1672}
1673
1674void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1675{
1676 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001677 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001678 arrayRef.push_back(cUnit->irb->getInt32(offset));
1679 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1680 cUnit->irb->SetDexOffset(node);
1681}
1682
1683// Attach method info as metadata to special intrinsic
1684void setMethodInfo(CompilationUnit* cUnit)
1685{
1686 // We don't want dex offset on this
1687 cUnit->irb->SetDexOffset(NULL);
1688 greenland::IntrinsicHelper::IntrinsicId id;
1689 id = greenland::IntrinsicHelper::MethodInfo;
1690 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1691 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1692 llvm::SmallVector<llvm::Value*, 2> regInfo;
1693 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1694 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1695 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1696 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1697 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1698 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1699 inst->setMetadata("RegInfo", regInfoNode);
1700 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1701 llvm::SmallVector<llvm::Value*, 50> pmap;
1702 for (int i = 0; i < promoSize; i++) {
1703 PromotionMap* p = &cUnit->promotionMap[i];
1704 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1705 ((p->fpReg & 0xff) << 16) |
1706 ((p->coreReg & 0xff) << 8) |
1707 ((p->fpLocation & 0xf) << 4) |
1708 (p->coreLocation & 0xf);
1709 pmap.push_back(cUnit->irb->getInt32(mapData));
1710 }
1711 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1712 inst->setMetadata("PromotionMap", mapNode);
1713 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1714}
1715
1716/* Handle the content in each basic block */
1717bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1718{
1719 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1720 cUnit->irb->SetInsertPoint(llvmBB);
1721 setDexOffset(cUnit, bb->startOffset);
1722
1723 if (bb->blockType == kEntryBlock) {
1724 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001725 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1726 cUnit->numDalvikRegisters, true,
1727 kAllocMisc);
1728 for (int i = 0; i < cUnit->numSSARegs; i++) {
1729 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1730 }
1731 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1732 if (canBeRef[i]) {
1733 cUnit->numShadowFrameEntries++;
1734 }
1735 }
1736 if (cUnit->numShadowFrameEntries > 0) {
1737 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1738 cUnit->numShadowFrameEntries, true,
1739 kAllocMisc);
1740 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1741 if (canBeRef[i]) {
1742 cUnit->shadowMap[j++] = i;
1743 }
1744 }
1745 greenland::IntrinsicHelper::IntrinsicId id =
1746 greenland::IntrinsicHelper::AllocaShadowFrame;
1747 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1748 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1749 cUnit->irb->CreateCall(func, entries);
1750 }
buzbee2cfc6392012-05-07 14:51:40 -07001751 } else if (bb->blockType == kExitBlock) {
1752 /*
1753 * Because of the differences between how MIR/LIR and llvm handle exit
1754 * blocks, we won't explicitly covert them. On the llvm-to-lir
1755 * path, it will need to be regenereated.
1756 */
1757 return false;
buzbee6969d502012-06-15 16:40:31 -07001758 } else if (bb->blockType == kExceptionHandling) {
1759 /*
1760 * Because we're deferring null checking, delete the associated empty
1761 * exception block.
Brian Carlstrom937b73e2012-08-01 16:09:16 -07001762 * TODO: add new block type for exception blocks that we generate
1763 * greenland code for.
buzbee6969d502012-06-15 16:40:31 -07001764 */
1765 llvmBB->eraseFromParent();
1766 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001767 }
1768
1769 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1770
1771 setDexOffset(cUnit, mir->offset);
1772
Brian Carlstrom937b73e2012-08-01 16:09:16 -07001773 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
1774 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
buzbee2cfc6392012-05-07 14:51:40 -07001775
1776 /* If we're compiling for the debugger, generate an update callout */
1777 if (cUnit->genDebugger) {
1778 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1779 //genDebuggerUpdate(cUnit, mir->offset);
1780 }
1781
Brian Carlstrom937b73e2012-08-01 16:09:16 -07001782 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
buzbee2cfc6392012-05-07 14:51:40 -07001783 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1784 continue;
1785 }
1786
1787 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1788 NULL /* labelList */);
1789 if (notHandled) {
1790 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Brian Carlstrom937b73e2012-08-01 16:09:16 -07001791 mir->offset, dalvikOpcode,
buzbee2cfc6392012-05-07 14:51:40 -07001792 Instruction::Name(dalvikOpcode),
1793 dalvikFormat);
1794 }
1795 }
1796
buzbee4be777b2012-07-12 14:38:18 -07001797 if (bb->blockType == kEntryBlock) {
1798 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1799 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001800 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1801 }
1802
1803 return false;
1804}
1805
buzbee4f4dfc72012-07-02 14:54:44 -07001806char remapShorty(char shortyType) {
1807 /*
1808 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1809 * and longs/doubles are represented as a pair of registers. When sub-word
1810 * arguments (and method results) are passed, they are extended to Dalvik
1811 * virtual register containers. Because llvm is picky about type consistency,
1812 * we must either cast the "real" type to 32-bit container multiple Dalvik
1813 * register types, or always use the expanded values.
1814 * Here, we're doing the latter. We map the shorty signature to container
1815 * types (which is valid so long as we always do a real expansion of passed
1816 * arguments and field loads).
1817 */
1818 switch(shortyType) {
1819 case 'Z' : shortyType = 'I'; break;
1820 case 'B' : shortyType = 'I'; break;
1821 case 'S' : shortyType = 'I'; break;
1822 case 'C' : shortyType = 'I'; break;
1823 default: break;
1824 }
1825 return shortyType;
1826}
1827
buzbee2cfc6392012-05-07 14:51:40 -07001828llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1829
1830 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001831 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001832 greenland::kAccurate);
1833
1834 // Get argument type
1835 std::vector<llvm::Type*> args_type;
1836
1837 // method object
1838 args_type.push_back(cUnit->irb->GetJMethodTy());
1839
1840 // Do we have a "this"?
1841 if ((cUnit->access_flags & kAccStatic) == 0) {
1842 args_type.push_back(cUnit->irb->GetJObjectTy());
1843 }
1844
1845 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001846 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001847 greenland::kAccurate));
1848 }
1849
1850 return llvm::FunctionType::get(ret_type, args_type, false);
1851}
1852
1853bool createFunction(CompilationUnit* cUnit) {
1854 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1855 /* with_signature */ false));
1856 llvm::FunctionType* func_type = getFunctionType(cUnit);
1857
1858 if (func_type == NULL) {
1859 return false;
1860 }
1861
1862 cUnit->func = llvm::Function::Create(func_type,
1863 llvm::Function::ExternalLinkage,
1864 func_name, cUnit->module);
1865
1866 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1867 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1868
1869 arg_iter->setName("method");
1870 ++arg_iter;
1871
1872 int startSReg = cUnit->numRegs;
1873
1874 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1875 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1876 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1877 }
1878
1879 return true;
1880}
1881
1882bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1883{
1884 // Skip the exit block
1885 if (bb->blockType == kExitBlock) {
1886 cUnit->idToBlockMap.Put(bb->id, NULL);
1887 } else {
1888 int offset = bb->startOffset;
1889 bool entryBlock = (bb->blockType == kEntryBlock);
1890 llvm::BasicBlock* llvmBB =
1891 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
Elliott Hughes74847412012-06-20 18:10:21 -07001892 StringPrintf(kLabelFormat, offset, bb->id),
buzbee2cfc6392012-05-07 14:51:40 -07001893 cUnit->func);
1894 if (entryBlock) {
1895 cUnit->entryBB = llvmBB;
1896 cUnit->placeholderBB =
1897 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1898 cUnit->func);
1899 }
1900 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1901 }
1902 return false;
1903}
1904
1905
1906/*
1907 * Convert MIR to LLVM_IR
1908 * o For each ssa name, create LLVM named value. Type these
1909 * appropriately, and ignore high half of wide and double operands.
1910 * o For each MIR basic block, create an LLVM basic block.
1911 * o Iterate through the MIR a basic block at a time, setting arguments
1912 * to recovered ssa name.
1913 */
1914void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
1915{
1916 initIR(cUnit);
1917 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
1918
1919 // Create the function
1920 createFunction(cUnit);
1921
1922 // Create an LLVM basic block for each MIR block in dfs preorder
1923 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
1924 kPreOrderDFSTraversal, false /* isIterative */);
1925 /*
1926 * Create an llvm named value for each MIR SSA name. Note: we'll use
1927 * placeholders for all non-argument values (because we haven't seen
1928 * the definition yet).
1929 */
1930 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
1931 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1932 arg_iter++; /* Skip path method */
1933 for (int i = 0; i < cUnit->numSSARegs; i++) {
1934 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07001935 RegLocation rlTemp = cUnit->regLocation[i];
1936 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07001937 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1938 } else if ((i < cUnit->numRegs) ||
1939 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07001940 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
1941 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07001942 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
1943 val->setName(llvmSSAName(cUnit, i));
buzbee2cfc6392012-05-07 14:51:40 -07001944 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
buzbee2cfc6392012-05-07 14:51:40 -07001945 } else {
1946 // Recover previously-created argument values
1947 llvm::Value* argVal = arg_iter++;
1948 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
1949 }
1950 }
buzbee2cfc6392012-05-07 14:51:40 -07001951
1952 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
1953 kPreOrderDFSTraversal, false /* Iterative */);
1954
buzbee4be777b2012-07-12 14:38:18 -07001955 /*
1956 * In a few rare cases of verification failure, the verifier will
1957 * replace one or more Dalvik opcodes with the special
1958 * throw-verification-failure opcode. This can leave the SSA graph
1959 * in an invalid state, as definitions may be lost, while uses retained.
1960 * To work around this problem, we insert placeholder definitions for
1961 * all Dalvik SSA regs in the "placeholder" block. Here, after
1962 * bitcode conversion is complete, we examine those placeholder definitions
1963 * and delete any with no references (which normally is all of them).
1964 *
1965 * If any definitions remain, we link the placeholder block into the
1966 * CFG. Otherwise, it is deleted.
1967 */
1968 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
1969 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
1970 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
1971 DCHECK(inst != NULL);
1972 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
1973 DCHECK(val != NULL);
1974 if (val->getNumUses() == 0) {
1975 inst->eraseFromParent();
1976 }
1977 }
1978 setDexOffset(cUnit, 0);
1979 if (cUnit->placeholderBB->empty()) {
1980 cUnit->placeholderBB->eraseFromParent();
1981 } else {
1982 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
1983 cUnit->irb->CreateBr(cUnit->entryTargetBB);
1984 cUnit->entryTargetBB = cUnit->placeholderBB;
1985 }
1986 cUnit->irb->SetInsertPoint(cUnit->entryBB);
1987 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07001988
Brian Carlstrom937b73e2012-08-01 16:09:16 -07001989 //llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction);
buzbee2cfc6392012-05-07 14:51:40 -07001990
buzbeead8f15e2012-06-18 14:49:45 -07001991 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
1992 // Write bitcode to file
1993 std::string errmsg;
1994 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
1995 oatReplaceSpecialChars(fname);
1996 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07001997 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07001998
buzbeead8f15e2012-06-18 14:49:45 -07001999 llvm::OwningPtr<llvm::tool_output_file> out_file(
2000 new llvm::tool_output_file(fname.c_str(), errmsg,
2001 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002002
buzbeead8f15e2012-06-18 14:49:45 -07002003 if (!errmsg.empty()) {
2004 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2005 }
2006
2007 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2008 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002009 }
buzbee2cfc6392012-05-07 14:51:40 -07002010}
2011
2012RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2013 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002014 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002015 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2016 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002017 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002018 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002019 // FIXME: need to be more robust, handle FP and be in a position to
2020 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002021 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2022 memset(&res, 0, sizeof(res));
2023 res.location = kLocPhysReg;
2024 res.lowReg = oatAllocTemp(cUnit);
2025 res.home = true;
2026 res.sRegLow = INVALID_SREG;
2027 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002028 llvm::Type* ty = val->getType();
2029 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2030 (ty == cUnit->irb->getDoubleTy()));
2031 if (res.wide) {
2032 res.highReg = oatAllocTemp(cUnit);
2033 }
buzbee4f1181f2012-06-22 13:52:12 -07002034 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002035 } else {
2036 DCHECK_EQ(valName[0], 'v');
2037 int baseSReg = INVALID_SREG;
2038 sscanf(valName.c_str(), "v%d_", &baseSReg);
2039 res = cUnit->regLocation[baseSReg];
2040 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002041 }
2042 } else {
2043 res = it->second;
2044 }
2045 return res;
2046}
2047
2048Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2049{
2050 Instruction::Code res = Instruction::NOP;
2051 if (isWide) {
2052 switch(op) {
2053 case kOpAdd: res = Instruction::ADD_LONG; break;
2054 case kOpSub: res = Instruction::SUB_LONG; break;
2055 case kOpMul: res = Instruction::MUL_LONG; break;
2056 case kOpDiv: res = Instruction::DIV_LONG; break;
2057 case kOpRem: res = Instruction::REM_LONG; break;
2058 case kOpAnd: res = Instruction::AND_LONG; break;
2059 case kOpOr: res = Instruction::OR_LONG; break;
2060 case kOpXor: res = Instruction::XOR_LONG; break;
2061 case kOpLsl: res = Instruction::SHL_LONG; break;
2062 case kOpLsr: res = Instruction::USHR_LONG; break;
2063 case kOpAsr: res = Instruction::SHR_LONG; break;
2064 default: LOG(FATAL) << "Unexpected OpKind " << op;
2065 }
2066 } else if (isConst){
2067 switch(op) {
2068 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2069 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2070 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2071 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2072 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2073 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2074 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2075 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2076 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2077 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2078 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2079 default: LOG(FATAL) << "Unexpected OpKind " << op;
2080 }
2081 } else {
2082 switch(op) {
2083 case kOpAdd: res = Instruction::ADD_INT; break;
2084 case kOpSub: res = Instruction::SUB_INT; break;
2085 case kOpMul: res = Instruction::MUL_INT; break;
2086 case kOpDiv: res = Instruction::DIV_INT; break;
2087 case kOpRem: res = Instruction::REM_INT; break;
2088 case kOpAnd: res = Instruction::AND_INT; break;
2089 case kOpOr: res = Instruction::OR_INT; break;
2090 case kOpXor: res = Instruction::XOR_INT; break;
2091 case kOpLsl: res = Instruction::SHL_INT; break;
2092 case kOpLsr: res = Instruction::USHR_INT; break;
2093 case kOpAsr: res = Instruction::SHR_INT; break;
2094 default: LOG(FATAL) << "Unexpected OpKind " << op;
2095 }
2096 }
2097 return res;
2098}
2099
buzbee4f1181f2012-06-22 13:52:12 -07002100Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2101{
2102 Instruction::Code res = Instruction::NOP;
2103 if (isWide) {
2104 switch(op) {
2105 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2106 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2107 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2108 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2109 case kOpRem: res = Instruction::REM_DOUBLE; break;
2110 default: LOG(FATAL) << "Unexpected OpKind " << op;
2111 }
2112 } else {
2113 switch(op) {
2114 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2115 case kOpSub: res = Instruction::SUB_FLOAT; break;
2116 case kOpMul: res = Instruction::MUL_FLOAT; break;
2117 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2118 case kOpRem: res = Instruction::REM_FLOAT; break;
2119 default: LOG(FATAL) << "Unexpected OpKind " << op;
2120 }
2121 }
2122 return res;
2123}
2124
2125void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2126{
2127 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002128 /*
2129 * Normally, we won't ever generate an FP operation with an immediate
2130 * operand (not supported in Dex instruction set). However, the IR builder
2131 * may insert them - in particular for createNegFP. Recognize this case
2132 * and deal with it.
2133 */
2134 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2135 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2136 DCHECK(op2C == NULL);
2137 if ((op1C != NULL) && (op == kOpSub)) {
2138 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2139 if (rlDest.wide) {
2140 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2141 } else {
2142 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2143 }
buzbee4f1181f2012-06-22 13:52:12 -07002144 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002145 DCHECK(op1C == NULL);
2146 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2147 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2148 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2149 if (rlDest.wide) {
2150 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2151 } else {
2152 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2153 }
buzbee4f1181f2012-06-22 13:52:12 -07002154 }
2155}
2156
buzbee101305f2012-06-28 18:00:56 -07002157void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2158 Instruction::Code opcode)
2159{
2160 RegLocation rlDest = getLoc(cUnit, inst);
2161 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2162 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2163}
2164
buzbee76592632012-06-29 15:18:35 -07002165void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2166{
2167 RegLocation rlDest = getLoc(cUnit, inst);
2168 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2169 Instruction::Code opcode;
2170 if (rlDest.wide) {
2171 if (rlSrc.wide) {
2172 opcode = Instruction::LONG_TO_DOUBLE;
2173 } else {
2174 opcode = Instruction::INT_TO_DOUBLE;
2175 }
2176 } else {
2177 if (rlSrc.wide) {
2178 opcode = Instruction::LONG_TO_FLOAT;
2179 } else {
2180 opcode = Instruction::INT_TO_FLOAT;
2181 }
2182 }
2183 genConversion(cUnit, opcode, rlDest, rlSrc);
2184}
2185
2186void cvtFPToInt(CompilationUnit* cUnit, llvm::Instruction* inst)
2187{
2188 RegLocation rlDest = getLoc(cUnit, inst);
2189 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2190 Instruction::Code opcode;
2191 if (rlDest.wide) {
2192 if (rlSrc.wide) {
2193 opcode = Instruction::DOUBLE_TO_LONG;
2194 } else {
2195 opcode = Instruction::FLOAT_TO_LONG;
2196 }
2197 } else {
2198 if (rlSrc.wide) {
2199 opcode = Instruction::DOUBLE_TO_INT;
2200 } else {
2201 opcode = Instruction::FLOAT_TO_INT;
2202 }
2203 }
2204 genConversion(cUnit, opcode, rlDest, rlSrc);
2205}
2206
2207void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2208{
2209 RegLocation rlDest = getLoc(cUnit, inst);
2210 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2211 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2212}
2213
2214void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2215{
2216 RegLocation rlDest = getLoc(cUnit, inst);
2217 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2218 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2219 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2220 storeValue(cUnit, rlDest, rlSrc);
2221}
2222
2223void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2224{
2225 RegLocation rlDest = getLoc(cUnit, inst);
2226 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2227 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2228}
2229
2230
buzbee101305f2012-06-28 18:00:56 -07002231void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2232{
2233 // TODO: evaluate src/tgt types and add general support for more than int to long
2234 RegLocation rlDest = getLoc(cUnit, inst);
2235 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2236 DCHECK(rlDest.wide);
2237 DCHECK(!rlSrc.wide);
2238 DCHECK(!rlDest.fp);
2239 DCHECK(!rlSrc.fp);
2240 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2241 if (rlSrc.location == kLocPhysReg) {
2242 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2243 } else {
2244 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2245 }
2246 if (isSigned) {
2247 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2248 } else {
2249 loadConstant(cUnit, rlResult.highReg, 0);
2250 }
2251 storeValueWide(cUnit, rlDest, rlResult);
2252}
2253
buzbee2cfc6392012-05-07 14:51:40 -07002254void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2255{
2256 RegLocation rlDest = getLoc(cUnit, inst);
2257 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002258 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002259 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2260 if ((op == kOpSub) && (lhsImm != NULL)) {
2261 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002262 if (rlSrc1.wide) {
2263 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2264 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2265 } else {
2266 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2267 lhsImm->getSExtValue());
2268 }
buzbee4f1181f2012-06-22 13:52:12 -07002269 return;
2270 }
2271 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002272 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2273 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002274 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2275 if (!rlDest.wide && (constRhs != NULL)) {
buzbee2cfc6392012-05-07 14:51:40 -07002276 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
buzbee9a2487f2012-07-26 14:01:13 -07002277 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002278 } else {
2279 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002280 RegLocation rlSrc2;
2281 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002282 // ir_builder converts NOT_LONG to xor src, -1. Restore
2283 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2284 DCHECK_EQ(-1L, constRhs->getSExtValue());
2285 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002286 rlSrc2 = rlSrc1;
2287 } else {
2288 rlSrc2 = getLoc(cUnit, rhs);
2289 }
buzbee2cfc6392012-05-07 14:51:40 -07002290 if (rlDest.wide) {
2291 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2292 } else {
2293 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2294 }
2295 }
2296}
2297
buzbee2a83e8f2012-07-13 16:42:30 -07002298void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2299 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002300{
buzbee2a83e8f2012-07-13 16:42:30 -07002301 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2302 RegLocation rlDest = getLoc(cUnit, callInst);
2303 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2304 llvm::Value* rhs = callInst->getArgOperand(1);
2305 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2306 DCHECK(!rlDest.wide);
2307 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002308 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002309 RegLocation rlShift = getLoc(cUnit, rhs);
2310 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2311 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2312 } else {
2313 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2314 }
buzbee101305f2012-06-28 18:00:56 -07002315 }
2316}
2317
buzbee2cfc6392012-05-07 14:51:40 -07002318void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2319{
2320 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2321 DCHECK(brInst != NULL);
2322 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2323 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2324 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2325}
2326
2327void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2328{
2329 // Nop - these have already been processed
2330}
2331
2332void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2333{
2334 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2335 llvm::Value* retVal = retInst->getReturnValue();
2336 if (retVal != NULL) {
2337 RegLocation rlSrc = getLoc(cUnit, retVal);
2338 if (rlSrc.wide) {
2339 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2340 } else {
2341 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2342 }
2343 }
2344 genExitSequence(cUnit);
2345}
2346
2347ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2348{
2349 ConditionCode res = kCondAl;
2350 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002351 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002352 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2353 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2354 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002355 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002356 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002357 default: LOG(FATAL) << "Unexpected llvm condition";
2358 }
2359 return res;
2360}
2361
2362void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2363{
2364 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2365 UNIMPLEMENTED(FATAL);
2366}
2367
2368void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2369 llvm::BranchInst* brInst)
2370{
2371 // Get targets
2372 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2373 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2374 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2375 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2376 // Get comparison operands
2377 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2378 ConditionCode cond = getCond(iCmpInst->getPredicate());
2379 llvm::Value* lhs = iCmpInst->getOperand(0);
2380 // Not expecting a constant as 1st operand
2381 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2382 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2383 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2384 llvm::Value* rhs = inst->getOperand(1);
2385#if defined(TARGET_MIPS)
2386 // Compare and branch in one shot
2387 (void)taken;
2388 (void)cond;
2389 (void)rhs;
2390 UNIMPLEMENTED(FATAL);
2391#else
2392 //Compare, then branch
2393 // TODO: handle fused CMP_LONG/IF_xxZ case
2394 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2395 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002396 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2397 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002398 } else {
2399 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2400 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2401 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2402 }
2403 opCondBranch(cUnit, cond, taken);
2404#endif
2405 // Fallthrough
2406 opUnconditionalBranch(cUnit, fallThrough);
2407}
2408
2409void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2410 llvm::Function* callee)
2411{
2412 UNIMPLEMENTED(FATAL);
2413}
2414
buzbee2cfc6392012-05-07 14:51:40 -07002415void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2416{
buzbee4f1181f2012-06-22 13:52:12 -07002417 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002418 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2419 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002420 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2421 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002422 if (rlSrc.wide) {
2423 storeValueWide(cUnit, rlDest, rlSrc);
2424 } else {
2425 storeValue(cUnit, rlDest, rlSrc);
2426 }
2427}
2428
2429// Note: Immediate arg is a ConstantInt regardless of result type
2430void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2431{
buzbee4f1181f2012-06-22 13:52:12 -07002432 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002433 llvm::ConstantInt* src =
2434 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2435 uint64_t immval = src->getZExtValue();
2436 RegLocation rlDest = getLoc(cUnit, callInst);
2437 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2438 if (rlDest.wide) {
2439 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2440 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2441 storeValueWide(cUnit, rlDest, rlResult);
2442 } else {
2443 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2444 storeValue(cUnit, rlDest, rlResult);
2445 }
2446}
2447
buzbee101305f2012-06-28 18:00:56 -07002448void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2449 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002450{
buzbee4f1181f2012-06-22 13:52:12 -07002451 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002452 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002453 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002454 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002455 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002456 if (isString) {
2457 genConstString(cUnit, index, rlDest);
2458 } else {
2459 genConstClass(cUnit, index, rlDest);
2460 }
2461}
2462
2463void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2464{
2465 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2466 llvm::ConstantInt* offsetVal =
2467 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2468 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2469 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002470}
2471
buzbee4f1181f2012-06-22 13:52:12 -07002472void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2473{
buzbee32412962012-06-26 16:27:56 -07002474 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002475 llvm::ConstantInt* typeIdxVal =
2476 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2477 uint32_t typeIdx = typeIdxVal->getZExtValue();
2478 RegLocation rlDest = getLoc(cUnit, callInst);
2479 genNewInstance(cUnit, typeIdx, rlDest);
2480}
2481
buzbee8fa0fda2012-06-27 15:44:52 -07002482void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2483{
2484 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2485 llvm::ConstantInt* typeIdxVal =
2486 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2487 uint32_t typeIdx = typeIdxVal->getZExtValue();
2488 llvm::Value* len = callInst->getArgOperand(1);
2489 RegLocation rlLen = getLoc(cUnit, len);
2490 RegLocation rlDest = getLoc(cUnit, callInst);
2491 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2492}
2493
2494void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2495{
2496 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2497 llvm::ConstantInt* typeIdxVal =
2498 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2499 uint32_t typeIdx = typeIdxVal->getZExtValue();
2500 llvm::Value* src = callInst->getArgOperand(1);
2501 RegLocation rlSrc = getLoc(cUnit, src);
2502 RegLocation rlDest = getLoc(cUnit, callInst);
2503 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2504}
2505
buzbee32412962012-06-26 16:27:56 -07002506void cvtThrowVerificationError(CompilationUnit* cUnit, llvm::CallInst* callInst)
2507{
2508 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2509 llvm::ConstantInt* info1 =
2510 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2511 llvm::ConstantInt* info2 =
2512 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2513 genThrowVerificationError(cUnit, info1->getZExtValue(), info2->getZExtValue());
2514}
2515
2516void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2517{
2518 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2519 llvm::Value* src = callInst->getArgOperand(0);
2520 RegLocation rlSrc = getLoc(cUnit, src);
2521 genThrow(cUnit, rlSrc);
2522}
2523
buzbee8fa0fda2012-06-27 15:44:52 -07002524void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2525 llvm::CallInst* callInst)
2526{
2527 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2528 llvm::ConstantInt* optFlags =
2529 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2530 llvm::Value* src = callInst->getArgOperand(1);
2531 RegLocation rlSrc = getLoc(cUnit, src);
2532 if (isEnter) {
2533 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2534 } else {
2535 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2536 }
2537}
2538
buzbee76592632012-06-29 15:18:35 -07002539void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002540{
2541 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2542 llvm::ConstantInt* optFlags =
2543 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2544 llvm::Value* src = callInst->getArgOperand(1);
2545 RegLocation rlSrc = getLoc(cUnit, src);
2546 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2547 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2548 RegLocation rlDest = getLoc(cUnit, callInst);
2549 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2550 int lenOffset = Array::LengthOffset().Int32Value();
2551 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2552 storeValue(cUnit, rlDest, rlResult);
2553}
2554
buzbee32412962012-06-26 16:27:56 -07002555void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2556{
2557 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
2558 int exOffset = Thread::ExceptionOffset().Int32Value();
2559 RegLocation rlDest = getLoc(cUnit, callInst);
2560 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2561#if defined(TARGET_X86)
2562 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
2563 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
2564#else
2565 int resetReg = oatAllocTemp(cUnit);
2566 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
2567 loadConstant(cUnit, resetReg, 0);
2568 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
2569 oatFreeTemp(cUnit, resetReg);
2570#endif
2571 storeValue(cUnit, rlDest, rlResult);
2572}
2573
buzbee4f1181f2012-06-22 13:52:12 -07002574void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2575 bool isObject)
2576{
buzbee32412962012-06-26 16:27:56 -07002577 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002578 llvm::ConstantInt* typeIdxVal =
2579 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2580 uint32_t typeIdx = typeIdxVal->getZExtValue();
2581 RegLocation rlDest = getLoc(cUnit, callInst);
2582 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2583}
2584
buzbee8fa0fda2012-06-27 15:44:52 -07002585void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2586 bool isObject)
2587{
2588 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2589 llvm::ConstantInt* typeIdxVal =
2590 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2591 uint32_t typeIdx = typeIdxVal->getZExtValue();
2592 llvm::Value* src = callInst->getArgOperand(1);
2593 RegLocation rlSrc = getLoc(cUnit, src);
2594 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2595}
2596
2597void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2598 int scale)
2599{
2600 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2601 llvm::ConstantInt* optFlags =
2602 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2603 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2604 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2605 RegLocation rlDest = getLoc(cUnit, callInst);
2606 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2607 rlDest, scale);
2608}
2609
2610void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002611 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002612{
2613 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2614 llvm::ConstantInt* optFlags =
2615 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2616 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2617 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2618 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002619 if (isObject) {
2620 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2621 rlSrc, scale);
2622 } else {
2623 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2624 rlSrc, scale);
2625 }
2626}
2627
2628void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2629{
2630 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2631}
2632
2633void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2634 OpSize size, int scale)
2635{
2636 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002637}
2638
buzbee101305f2012-06-28 18:00:56 -07002639void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2640 bool isWide, bool isObj)
2641{
2642 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2643 llvm::ConstantInt* optFlags =
2644 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2645 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2646 llvm::ConstantInt* fieldIdx =
2647 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2648 RegLocation rlDest = getLoc(cUnit, callInst);
2649 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2650 size, rlDest, rlObj, isWide, isObj);
2651}
2652
2653void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2654 bool isWide, bool isObj)
2655{
2656 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2657 llvm::ConstantInt* optFlags =
2658 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2659 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2660 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2661 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002662 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002663 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2664 size, rlSrc, rlObj, isWide, isObj);
2665}
2666
2667void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2668{
2669 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2670 llvm::ConstantInt* typeIdx =
2671 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2672 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2673 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2674}
2675
buzbee76592632012-06-29 15:18:35 -07002676void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2677 Instruction::Code opcode)
2678{
2679 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2680 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2681 RegLocation rlDest = getLoc(cUnit, callInst);
2682 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2683}
2684
2685void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2686{
2687 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2688 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2689 RegLocation rlDest = getLoc(cUnit, callInst);
2690 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2691}
2692
buzbeef58c12c2012-07-03 15:06:29 -07002693void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2694{
2695 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2696 DCHECK(swInst != NULL);
2697 llvm::Value* testVal = swInst->getCondition();
2698 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2699 DCHECK(tableOffsetNode != NULL);
2700 llvm::ConstantInt* tableOffsetValue =
2701 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2702 int32_t tableOffset = tableOffsetValue->getSExtValue();
2703 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeea1da8a52012-07-09 14:00:21 -07002704 const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2705 u2 tableMagic = *table;
2706 if (tableMagic == 0x100) {
2707 genPackedSwitch(cUnit, tableOffset, rlSrc);
2708 } else {
2709 DCHECK_EQ(tableMagic, 0x200);
2710 genSparseSwitch(cUnit, tableOffset, rlSrc);
2711 }
buzbeef58c12c2012-07-03 15:06:29 -07002712}
2713
buzbee6969d502012-06-15 16:40:31 -07002714void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002715 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002716{
2717 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2718 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002719 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002720 info->result.location = kLocInvalid;
2721 } else {
2722 info->result = getLoc(cUnit, callInst);
2723 }
2724 llvm::ConstantInt* invokeTypeVal =
2725 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2726 llvm::ConstantInt* methodIndexVal =
2727 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2728 llvm::ConstantInt* optFlagsVal =
2729 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2730 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2731 info->index = methodIndexVal->getZExtValue();
2732 info->optFlags = optFlagsVal->getZExtValue();
2733 info->offset = cUnit->currentDalvikOffset;
2734
buzbee6969d502012-06-15 16:40:31 -07002735 // Count the argument words, and then build argument array.
2736 info->numArgWords = 0;
2737 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2738 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2739 info->numArgWords += tLoc.wide ? 2 : 1;
2740 }
2741 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2742 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2743 // Now, fill in the location records, synthesizing high loc of wide vals
2744 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002745 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002746 if (info->args[next].wide) {
2747 next++;
2748 // TODO: Might make sense to mark this as an invalid loc
2749 info->args[next].origSReg = info->args[next-1].origSReg+1;
2750 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2751 }
2752 next++;
2753 }
buzbee4f4dfc72012-07-02 14:54:44 -07002754 // TODO - rework such that we no longer need isRange
2755 info->isRange = (info->numArgWords > 5);
2756
buzbee76592632012-06-29 15:18:35 -07002757 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002758 genFilledNewArray(cUnit, info);
2759 } else {
2760 genInvoke(cUnit, info);
2761 }
buzbee6969d502012-06-15 16:40:31 -07002762}
2763
buzbeead8f15e2012-06-18 14:49:45 -07002764/* Look up the RegLocation associated with a Value. Must already be defined */
2765RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2766{
2767 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2768 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2769 return it->second;
2770}
2771
buzbee2cfc6392012-05-07 14:51:40 -07002772bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2773{
2774 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2775 // Define the starting label
2776 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2777 // Extract the starting offset from the block's name
2778 if (!isEntry) {
2779 const char* blockName = bb->getName().str().c_str();
2780 int dummy;
Elliott Hughes74847412012-06-20 18:10:21 -07002781 sscanf(blockName, kLabelFormat, &blockLabel->operands[0], &dummy);
buzbee2cfc6392012-05-07 14:51:40 -07002782 }
2783 // Set the label kind
2784 blockLabel->opcode = kPseudoNormalBlockLabel;
2785 // Insert the label
2786 oatAppendLIR(cUnit, blockLabel);
2787
2788 // Free temp registers and reset redundant store tracking */
2789 oatResetRegPool(cUnit);
2790 oatResetDefTracking(cUnit);
2791
2792 //TODO: restore oat incoming liveness optimization
2793 oatClobberAllRegs(cUnit);
2794
buzbee6969d502012-06-15 16:40:31 -07002795 LIR* headLIR = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07002796
2797 if (isEntry) {
2798 cUnit->currentDalvikOffset = 0;
buzbeead8f15e2012-06-18 14:49:45 -07002799 RegLocation* argLocs = (RegLocation*)
2800 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2801 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2802 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2803 for (unsigned i = 0; it != it_end; ++it) {
2804 llvm::Value* val = it;
2805 argLocs[i++] = valToLoc(cUnit, val);
2806 llvm::Type* ty = val->getType();
2807 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2808 argLocs[i++].sRegLow = INVALID_SREG;
2809 }
2810 }
2811 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
buzbee2cfc6392012-05-07 14:51:40 -07002812 }
2813
2814 // Visit all of the instructions in the block
2815 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2816 llvm::Instruction* inst = it;
2817 llvm::BasicBlock::iterator nextIt = ++it;
2818 // Extract the Dalvik offset from the instruction
2819 uint32_t opcode = inst->getOpcode();
2820 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2821 if (dexOffsetNode != NULL) {
2822 llvm::ConstantInt* dexOffsetValue =
2823 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2824 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2825 }
2826
buzbee6969d502012-06-15 16:40:31 -07002827 oatResetRegPool(cUnit);
2828 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2829 oatClobberAllRegs(cUnit);
2830 }
2831
2832 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2833 oatResetDefTracking(cUnit);
2834 }
2835
2836#ifndef NDEBUG
2837 /* Reset temp tracking sanity check */
2838 cUnit->liveSReg = INVALID_SREG;
2839#endif
2840
2841 LIR* boundaryLIR;
2842 const char* instStr = "boundary";
2843 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
2844 (intptr_t) instStr);
2845 cUnit->boundaryMap.Overwrite(cUnit->currentDalvikOffset, boundaryLIR);
2846
2847 /* Remember the first LIR for thisl block*/
2848 if (headLIR == NULL) {
2849 headLIR = boundaryLIR;
2850 headLIR->defMask = ENCODE_ALL;
2851 }
2852
buzbee2cfc6392012-05-07 14:51:40 -07002853 switch(opcode) {
2854
2855 case llvm::Instruction::ICmp: {
2856 llvm::Instruction* nextInst = nextIt;
2857 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2858 if (brInst != NULL /* and... */) {
2859 cvtICmpBr(cUnit, inst, brInst);
2860 ++it;
2861 } else {
2862 cvtICmp(cUnit, inst);
2863 }
2864 }
2865 break;
2866
2867 case llvm::Instruction::Call: {
2868 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2869 llvm::Function* callee = callInst->getCalledFunction();
2870 greenland::IntrinsicHelper::IntrinsicId id =
2871 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2872 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07002873 case greenland::IntrinsicHelper::AllocaShadowFrame:
2874 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07002875 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07002876 // Ignore shadow frame stuff for quick compiler
2877 break;
buzbee2cfc6392012-05-07 14:51:40 -07002878 case greenland::IntrinsicHelper::CopyInt:
2879 case greenland::IntrinsicHelper::CopyObj:
2880 case greenland::IntrinsicHelper::CopyFloat:
2881 case greenland::IntrinsicHelper::CopyLong:
2882 case greenland::IntrinsicHelper::CopyDouble:
2883 cvtCopy(cUnit, callInst);
2884 break;
2885 case greenland::IntrinsicHelper::ConstInt:
2886 case greenland::IntrinsicHelper::ConstObj:
2887 case greenland::IntrinsicHelper::ConstLong:
2888 case greenland::IntrinsicHelper::ConstFloat:
2889 case greenland::IntrinsicHelper::ConstDouble:
2890 cvtConst(cUnit, callInst);
2891 break;
buzbee4f1181f2012-06-22 13:52:12 -07002892 case greenland::IntrinsicHelper::DivInt:
2893 case greenland::IntrinsicHelper::DivLong:
2894 cvtBinOp(cUnit, kOpDiv, inst);
2895 break;
2896 case greenland::IntrinsicHelper::RemInt:
2897 case greenland::IntrinsicHelper::RemLong:
2898 cvtBinOp(cUnit, kOpRem, inst);
2899 break;
buzbee2cfc6392012-05-07 14:51:40 -07002900 case greenland::IntrinsicHelper::MethodInfo:
buzbeead8f15e2012-06-18 14:49:45 -07002901 // Already dealt with - just ignore it here.
buzbee2cfc6392012-05-07 14:51:40 -07002902 break;
2903 case greenland::IntrinsicHelper::CheckSuspend:
2904 genSuspendTest(cUnit, 0 /* optFlags already applied */);
2905 break;
buzbee4f1181f2012-06-22 13:52:12 -07002906 case greenland::IntrinsicHelper::HLInvokeObj:
buzbee8fa0fda2012-06-27 15:44:52 -07002907 case greenland::IntrinsicHelper::HLInvokeFloat:
2908 case greenland::IntrinsicHelper::HLInvokeDouble:
2909 case greenland::IntrinsicHelper::HLInvokeLong:
2910 case greenland::IntrinsicHelper::HLInvokeInt:
buzbee101305f2012-06-28 18:00:56 -07002911 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
buzbee4f1181f2012-06-22 13:52:12 -07002912 break;
buzbee6969d502012-06-15 16:40:31 -07002913 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbee101305f2012-06-28 18:00:56 -07002914 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
2915 break;
2916 case greenland::IntrinsicHelper::FilledNewArray:
2917 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
2918 break;
2919 case greenland::IntrinsicHelper::FillArrayData:
2920 cvtFillArrayData(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07002921 break;
2922 case greenland::IntrinsicHelper::ConstString:
buzbee101305f2012-06-28 18:00:56 -07002923 cvtConstObject(cUnit, callInst, true /* isString */);
2924 break;
2925 case greenland::IntrinsicHelper::ConstClass:
2926 cvtConstObject(cUnit, callInst, false /* isString */);
2927 break;
2928 case greenland::IntrinsicHelper::CheckCast:
2929 cvtCheckCast(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07002930 break;
buzbee4f1181f2012-06-22 13:52:12 -07002931 case greenland::IntrinsicHelper::NewInstance:
2932 cvtNewInstance(cUnit, callInst);
2933 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002934 case greenland::IntrinsicHelper::HLSgetObject:
buzbee4f1181f2012-06-22 13:52:12 -07002935 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
2936 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002937 case greenland::IntrinsicHelper::HLSget:
2938 case greenland::IntrinsicHelper::HLSgetFloat:
2939 case greenland::IntrinsicHelper::HLSgetBoolean:
2940 case greenland::IntrinsicHelper::HLSgetByte:
2941 case greenland::IntrinsicHelper::HLSgetChar:
2942 case greenland::IntrinsicHelper::HLSgetShort:
2943 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
2944 break;
2945 case greenland::IntrinsicHelper::HLSgetWide:
2946 case greenland::IntrinsicHelper::HLSgetDouble:
2947 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
2948 break;
buzbee76592632012-06-29 15:18:35 -07002949 case greenland::IntrinsicHelper::HLSput:
2950 case greenland::IntrinsicHelper::HLSputFloat:
2951 case greenland::IntrinsicHelper::HLSputBoolean:
2952 case greenland::IntrinsicHelper::HLSputByte:
2953 case greenland::IntrinsicHelper::HLSputChar:
2954 case greenland::IntrinsicHelper::HLSputShort:
2955 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
2956 break;
2957 case greenland::IntrinsicHelper::HLSputWide:
2958 case greenland::IntrinsicHelper::HLSputDouble:
2959 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
2960 break;
buzbeea1da8a52012-07-09 14:00:21 -07002961 case greenland::IntrinsicHelper::HLSputObject:
2962 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
2963 break;
buzbee32412962012-06-26 16:27:56 -07002964 case greenland::IntrinsicHelper::GetException:
2965 cvtMoveException(cUnit, callInst);
2966 break;
2967 case greenland::IntrinsicHelper::Throw:
2968 cvtThrow(cUnit, callInst);
2969 break;
2970 case greenland::IntrinsicHelper::ThrowVerificationError:
buzbee8fa0fda2012-06-27 15:44:52 -07002971 cvtThrowVerificationError(cUnit, callInst);
buzbee32412962012-06-26 16:27:56 -07002972 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002973 case greenland::IntrinsicHelper::MonitorEnter:
2974 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
2975 break;
2976 case greenland::IntrinsicHelper::MonitorExit:
2977 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
2978 break;
2979 case greenland::IntrinsicHelper::ArrayLength:
buzbee76592632012-06-29 15:18:35 -07002980 cvtArrayLength(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07002981 break;
2982 case greenland::IntrinsicHelper::NewArray:
2983 cvtNewArray(cUnit, callInst);
2984 break;
2985 case greenland::IntrinsicHelper::InstanceOf:
2986 cvtInstanceOf(cUnit, callInst);
2987 break;
2988
2989 case greenland::IntrinsicHelper::HLArrayGet:
2990 case greenland::IntrinsicHelper::HLArrayGetObject:
2991 case greenland::IntrinsicHelper::HLArrayGetFloat:
2992 cvtAget(cUnit, callInst, kWord, 2);
2993 break;
2994 case greenland::IntrinsicHelper::HLArrayGetWide:
2995 case greenland::IntrinsicHelper::HLArrayGetDouble:
2996 cvtAget(cUnit, callInst, kLong, 3);
2997 break;
2998 case greenland::IntrinsicHelper::HLArrayGetBoolean:
2999 cvtAget(cUnit, callInst, kUnsignedByte, 0);
3000 break;
3001 case greenland::IntrinsicHelper::HLArrayGetByte:
3002 cvtAget(cUnit, callInst, kSignedByte, 0);
3003 break;
3004 case greenland::IntrinsicHelper::HLArrayGetChar:
3005 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
3006 break;
3007 case greenland::IntrinsicHelper::HLArrayGetShort:
3008 cvtAget(cUnit, callInst, kSignedHalf, 1);
3009 break;
3010
3011 case greenland::IntrinsicHelper::HLArrayPut:
buzbee8fa0fda2012-06-27 15:44:52 -07003012 case greenland::IntrinsicHelper::HLArrayPutFloat:
buzbeef1f86362012-07-10 15:18:31 -07003013 cvtAputPrimitive(cUnit, callInst, kWord, 2);
3014 break;
3015 case greenland::IntrinsicHelper::HLArrayPutObject:
3016 cvtAputObj(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07003017 break;
3018 case greenland::IntrinsicHelper::HLArrayPutWide:
3019 case greenland::IntrinsicHelper::HLArrayPutDouble:
buzbeef1f86362012-07-10 15:18:31 -07003020 cvtAputPrimitive(cUnit, callInst, kLong, 3);
buzbee8fa0fda2012-06-27 15:44:52 -07003021 break;
3022 case greenland::IntrinsicHelper::HLArrayPutBoolean:
buzbeef1f86362012-07-10 15:18:31 -07003023 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
buzbee8fa0fda2012-06-27 15:44:52 -07003024 break;
3025 case greenland::IntrinsicHelper::HLArrayPutByte:
buzbeef1f86362012-07-10 15:18:31 -07003026 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
buzbee8fa0fda2012-06-27 15:44:52 -07003027 break;
3028 case greenland::IntrinsicHelper::HLArrayPutChar:
buzbeef1f86362012-07-10 15:18:31 -07003029 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
buzbee8fa0fda2012-06-27 15:44:52 -07003030 break;
3031 case greenland::IntrinsicHelper::HLArrayPutShort:
buzbeef1f86362012-07-10 15:18:31 -07003032 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
buzbee8fa0fda2012-06-27 15:44:52 -07003033 break;
3034
buzbee101305f2012-06-28 18:00:56 -07003035 case greenland::IntrinsicHelper::HLIGet:
3036 case greenland::IntrinsicHelper::HLIGetFloat:
3037 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3038 break;
3039 case greenland::IntrinsicHelper::HLIGetObject:
3040 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3041 break;
3042 case greenland::IntrinsicHelper::HLIGetWide:
3043 case greenland::IntrinsicHelper::HLIGetDouble:
3044 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3045 break;
3046 case greenland::IntrinsicHelper::HLIGetBoolean:
3047 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3048 false /* obj */);
3049 break;
3050 case greenland::IntrinsicHelper::HLIGetByte:
3051 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3052 false /* obj */);
3053 break;
3054 case greenland::IntrinsicHelper::HLIGetChar:
3055 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3056 false /* obj */);
3057 break;
3058 case greenland::IntrinsicHelper::HLIGetShort:
3059 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3060 false /* obj */);
3061 break;
3062
3063 case greenland::IntrinsicHelper::HLIPut:
3064 case greenland::IntrinsicHelper::HLIPutFloat:
3065 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3066 break;
3067 case greenland::IntrinsicHelper::HLIPutObject:
3068 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3069 break;
3070 case greenland::IntrinsicHelper::HLIPutWide:
3071 case greenland::IntrinsicHelper::HLIPutDouble:
3072 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3073 break;
3074 case greenland::IntrinsicHelper::HLIPutBoolean:
3075 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3076 false /* obj */);
3077 break;
3078 case greenland::IntrinsicHelper::HLIPutByte:
3079 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3080 false /* obj */);
3081 break;
3082 case greenland::IntrinsicHelper::HLIPutChar:
3083 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3084 false /* obj */);
3085 break;
3086 case greenland::IntrinsicHelper::HLIPutShort:
3087 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3088 false /* obj */);
3089 break;
3090
3091 case greenland::IntrinsicHelper::IntToChar:
3092 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3093 break;
3094 case greenland::IntrinsicHelper::IntToShort:
3095 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3096 break;
3097 case greenland::IntrinsicHelper::IntToByte:
3098 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3099 break;
3100
buzbee76592632012-06-29 15:18:35 -07003101 case greenland::IntrinsicHelper::CmplFloat:
3102 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3103 break;
3104 case greenland::IntrinsicHelper::CmpgFloat:
3105 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3106 break;
3107 case greenland::IntrinsicHelper::CmplDouble:
3108 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3109 break;
3110 case greenland::IntrinsicHelper::CmpgDouble:
3111 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3112 break;
3113
3114 case greenland::IntrinsicHelper::CmpLong:
3115 cvtLongCompare(cUnit, callInst);
3116 break;
3117
buzbee2a83e8f2012-07-13 16:42:30 -07003118 case greenland::IntrinsicHelper::SHLLong:
3119 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
buzbee2cfc6392012-05-07 14:51:40 -07003120 break;
buzbee2a83e8f2012-07-13 16:42:30 -07003121 case greenland::IntrinsicHelper::SHRLong:
3122 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3123 break;
3124 case greenland::IntrinsicHelper::USHRLong:
3125 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3126 break;
3127 case greenland::IntrinsicHelper::SHLInt:
3128 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3129 break;
3130 case greenland::IntrinsicHelper::SHRInt:
3131 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3132 break;
3133 case greenland::IntrinsicHelper::USHRInt:
3134 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3135 break;
3136
buzbee2cfc6392012-05-07 14:51:40 -07003137 default:
3138 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3139 << cUnit->intrinsic_helper->GetName(id);
3140 }
3141 }
3142 break;
3143
3144 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3145 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3146 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3147 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3148 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3149 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3150 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3151 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3152 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003153 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3154 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
buzbee4f1181f2012-06-22 13:52:12 -07003155 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3156 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3157 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3158 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3159 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
buzbee76592632012-06-29 15:18:35 -07003160 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
3161 case llvm::Instruction::FPToSI: cvtFPToInt(cUnit, inst); break;
3162 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3163 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3164 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003165
buzbee101305f2012-06-28 18:00:56 -07003166 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3167 break;
3168 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3169 break;
3170
buzbeef58c12c2012-07-03 15:06:29 -07003171 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3172
buzbee32412962012-06-26 16:27:56 -07003173 case llvm::Instruction::Unreachable:
3174 break; // FIXME: can we really ignore these?
3175
buzbee2a83e8f2012-07-13 16:42:30 -07003176 case llvm::Instruction::Shl:
3177 case llvm::Instruction::LShr:
3178 case llvm::Instruction::AShr:
buzbee2cfc6392012-05-07 14:51:40 -07003179 case llvm::Instruction::Invoke:
buzbee2cfc6392012-05-07 14:51:40 -07003180 case llvm::Instruction::FPToUI:
buzbee2cfc6392012-05-07 14:51:40 -07003181 case llvm::Instruction::UIToFP:
buzbee2cfc6392012-05-07 14:51:40 -07003182 case llvm::Instruction::PtrToInt:
3183 case llvm::Instruction::IntToPtr:
buzbee2cfc6392012-05-07 14:51:40 -07003184 case llvm::Instruction::FCmp:
buzbee2cfc6392012-05-07 14:51:40 -07003185 case llvm::Instruction::URem:
3186 case llvm::Instruction::UDiv:
3187 case llvm::Instruction::Resume:
buzbee2cfc6392012-05-07 14:51:40 -07003188 case llvm::Instruction::Alloca:
3189 case llvm::Instruction::GetElementPtr:
3190 case llvm::Instruction::Fence:
3191 case llvm::Instruction::AtomicCmpXchg:
3192 case llvm::Instruction::AtomicRMW:
3193 case llvm::Instruction::BitCast:
3194 case llvm::Instruction::VAArg:
3195 case llvm::Instruction::Select:
3196 case llvm::Instruction::UserOp1:
3197 case llvm::Instruction::UserOp2:
3198 case llvm::Instruction::ExtractElement:
3199 case llvm::Instruction::InsertElement:
3200 case llvm::Instruction::ShuffleVector:
3201 case llvm::Instruction::ExtractValue:
3202 case llvm::Instruction::InsertValue:
3203 case llvm::Instruction::LandingPad:
3204 case llvm::Instruction::IndirectBr:
3205 case llvm::Instruction::Load:
3206 case llvm::Instruction::Store:
3207 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3208
3209 default:
buzbee2a83e8f2012-07-13 16:42:30 -07003210 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3211 break;
buzbee2cfc6392012-05-07 14:51:40 -07003212 }
3213 }
buzbee6969d502012-06-15 16:40:31 -07003214
3215 if (headLIR != NULL) {
3216 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
3217 }
buzbee2cfc6392012-05-07 14:51:40 -07003218 return false;
3219}
3220
3221/*
3222 * Convert LLVM_IR to MIR:
3223 * o Iterate through the LLVM_IR and construct a graph using
3224 * standard MIR building blocks.
3225 * o Perform a basic-block optimization pass to remove unnecessary
3226 * store/load sequences.
3227 * o Convert the LLVM Value operands into RegLocations where applicable.
3228 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3229 * o Perform register promotion
3230 * o Iterate through the graph a basic block at a time, generating
3231 * LIR.
3232 * o Assemble LIR as usual.
3233 * o Profit.
3234 */
3235void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3236{
buzbeead8f15e2012-06-18 14:49:45 -07003237 llvm::Function* func = cUnit->func;
3238 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003239 // Allocate a list for LIR basic block labels
3240 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07003241 (LIR*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3242 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003243 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003244 for (llvm::Function::iterator i = func->begin(),
3245 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003246 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3247 &labelList[nextLabel++]);
3248 }
buzbeead8f15e2012-06-18 14:49:45 -07003249
3250 /*
3251 * Keep honest - clear regLocations, Value => RegLocation,
3252 * promotion map and VmapTables.
3253 */
3254 cUnit->locMap.clear(); // Start fresh
3255 cUnit->regLocation = NULL;
3256 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3257 i++) {
3258 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3259 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3260 }
3261 cUnit->coreSpillMask = 0;
3262 cUnit->numCoreSpills = 0;
3263 cUnit->fpSpillMask = 0;
3264 cUnit->numFPSpills = 0;
3265 cUnit->coreVmapTable.clear();
3266 cUnit->fpVmapTable.clear();
3267 oatAdjustSpillMask(cUnit);
3268 cUnit->frameSize = oatComputeFrameSize(cUnit);
3269
3270 /*
3271 * At this point, we've lost all knowledge of register promotion.
3272 * Rebuild that info from the MethodInfo intrinsic (if it
3273 * exists - not required for correctness).
3274 */
3275 // TODO: find and recover MethodInfo.
3276
3277 // Create RegLocations for arguments
3278 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3279 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3280 for (; it != it_end; ++it) {
3281 llvm::Value* val = it;
3282 createLocFromValue(cUnit, val);
3283 }
3284 // Create RegLocations for all non-argument defintions
3285 for (llvm::inst_iterator i = llvm::inst_begin(func),
3286 e = llvm::inst_end(func); i != e; ++i) {
3287 llvm::Value* val = &*i;
3288 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3289 createLocFromValue(cUnit, val);
3290 }
3291 }
3292
buzbee2cfc6392012-05-07 14:51:40 -07003293 // Walk the blocks, generating code.
3294 for (llvm::Function::iterator i = cUnit->func->begin(),
3295 e = cUnit->func->end(); i != e; ++i) {
3296 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3297 }
3298
3299 handleSuspendLaunchpads(cUnit);
3300
3301 handleThrowLaunchpads(cUnit);
3302
3303 handleIntrinsicLaunchpads(cUnit);
3304
3305 freeIR(cUnit);
3306}
3307
3308
3309} // namespace art
3310
3311#endif // ART_USE_QUICK_COMPILER