blob: 92cc6ccf056ac2b35a5c8c16f124c0fd9108b447 [file] [log] [blame]
buzbee2cfc6392012-05-07 14:51:40 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#if defined(ART_USE_QUICK_COMPILER)
18
19#include "object_utils.h"
20
21#include <llvm/Support/ToolOutputFile.h>
22#include <llvm/Bitcode/ReaderWriter.h>
23#include <llvm/Analysis/Verifier.h>
24#include <llvm/Metadata.h>
25#include <llvm/ADT/DepthFirstIterator.h>
26#include <llvm/Instruction.h>
27#include <llvm/Type.h>
28#include <llvm/Instructions.h>
29#include <llvm/Support/Casting.h>
buzbeead8f15e2012-06-18 14:49:45 -070030#include <llvm/Support/InstIterator.h>
buzbee2cfc6392012-05-07 14:51:40 -070031
Elliott Hughes74847412012-06-20 18:10:21 -070032static const char* kLabelFormat = "L0x%x_%d";
buzbee2cfc6392012-05-07 14:51:40 -070033
34namespace art {
35extern const RegLocation badLoc;
buzbeeb03f4872012-06-11 15:22:11 -070036RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070037
38llvm::BasicBlock* getLLVMBlock(CompilationUnit* cUnit, int id)
39{
40 return cUnit->idToBlockMap.Get(id);
41}
42
43llvm::Value* getLLVMValue(CompilationUnit* cUnit, int sReg)
44{
45 return (llvm::Value*)oatGrowableListGetElement(&cUnit->llvmValues, sReg);
46}
47
48// Replace the placeholder value with the real definition
49void defineValue(CompilationUnit* cUnit, llvm::Value* val, int sReg)
50{
51 llvm::Value* placeholder = getLLVMValue(cUnit, sReg);
52 CHECK(placeholder != NULL) << "Null placeholder - shouldn't happen";
53 placeholder->replaceAllUsesWith(val);
54 val->takeName(placeholder);
55 cUnit->llvmValues.elemList[sReg] = (intptr_t)val;
56}
57
58llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
59{
60 llvm::Type* res = NULL;
61 if (loc.wide) {
62 if (loc.fp)
buzbee4f1181f2012-06-22 13:52:12 -070063 res = cUnit->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070064 else
buzbee4f1181f2012-06-22 13:52:12 -070065 res = cUnit->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070066 } else {
67 if (loc.fp) {
buzbee4f1181f2012-06-22 13:52:12 -070068 res = cUnit->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070069 } else {
70 if (loc.ref)
71 res = cUnit->irb->GetJObjectTy();
72 else
buzbee4f1181f2012-06-22 13:52:12 -070073 res = cUnit->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -070074 }
75 }
76 return res;
77}
78
buzbeead8f15e2012-06-18 14:49:45 -070079/* Create an in-memory RegLocation from an llvm Value. */
80void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
81{
82 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
83 std::string s(val->getName().str());
84 const char* valName = s.c_str();
buzbeead8f15e2012-06-18 14:49:45 -070085 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
86 DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
87 int baseSReg = INVALID_SREG;
88 int subscript = -1;
89 sscanf(valName, "v%d_%d", &baseSReg, &subscript);
90 if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
91 baseSReg = SSA_METHOD_BASEREG;
92 subscript = 0;
93 }
buzbeead8f15e2012-06-18 14:49:45 -070094 DCHECK_NE(baseSReg, INVALID_SREG);
95 DCHECK_NE(subscript, -1);
96 // TODO: redo during C++'ification
97 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
98 INVALID_REG, INVALID_SREG, INVALID_SREG};
99 llvm::Type* ty = val->getType();
100 loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
101 (ty == cUnit->irb->getDoubleTy()));
102 loc.defined = true;
103 if ((ty == cUnit->irb->getFloatTy()) ||
104 (ty == cUnit->irb->getDoubleTy())) {
105 loc.fp = true;
106 } else if (ty == cUnit->irb->GetJObjectTy()) {
107 loc.ref = true;
108 } else {
109 loc.core = true;
110 }
111 loc.home = false; // Will change during promotion
112 loc.sRegLow = baseSReg;
113 loc.origSReg = cUnit->locMap.size();
114 cUnit->locMap.Put(val, loc);
115}
116
buzbee2cfc6392012-05-07 14:51:40 -0700117void initIR(CompilationUnit* cUnit)
118{
119 cUnit->context = new llvm::LLVMContext();
120 cUnit->module = new llvm::Module("art", *cUnit->context);
121 llvm::StructType::create(*cUnit->context, "JavaObject");
122 llvm::StructType::create(*cUnit->context, "Method");
123 llvm::StructType::create(*cUnit->context, "Thread");
124 cUnit->intrinsic_helper =
125 new greenland::IntrinsicHelper(*cUnit->context, *cUnit->module);
126 cUnit->irb =
127 new greenland::IRBuilder(*cUnit->context, *cUnit->module,
128 *cUnit->intrinsic_helper);
129}
130
131void freeIR(CompilationUnit* cUnit)
132{
133 delete cUnit->irb;
134 delete cUnit->intrinsic_helper;
135 delete cUnit->module;
136 delete cUnit->context;
137}
138
139const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
140 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
141}
142
buzbee8fa0fda2012-06-27 15:44:52 -0700143void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
144 greenland::IntrinsicHelper::IntrinsicId id,
145 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700146{
buzbee8fa0fda2012-06-27 15:44:52 -0700147 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700148 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700149 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
150 defineValue(cUnit, res, rlDest.origSReg);
151}
152
153void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
154 greenland::IntrinsicHelper::IntrinsicId id,
155 RegLocation rlSrc)
156{
157 llvm::SmallVector<llvm::Value*, 2> args;
158 args.push_back(cUnit->irb->getInt32(fieldIndex));
159 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
160 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
161 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700162}
163
buzbee101305f2012-06-28 18:00:56 -0700164void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
165 RegLocation rlArray)
166{
167 greenland::IntrinsicHelper::IntrinsicId id;
168 id = greenland::IntrinsicHelper::FillArrayData;
169 llvm::SmallVector<llvm::Value*, 2> args;
170 args.push_back(cUnit->irb->getInt32(offset));
171 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
172 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
173 cUnit->irb->CreateCall(intr, args);
174}
175
buzbee2cfc6392012-05-07 14:51:40 -0700176llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
177 RegLocation loc)
178{
179 greenland::IntrinsicHelper::IntrinsicId id;
180 if (loc.wide) {
181 if (loc.fp) {
182 id = greenland::IntrinsicHelper::ConstDouble;
183 } else {
184 id = greenland::IntrinsicHelper::ConstLong;
185 }
186 } else {
187 if (loc.fp) {
188 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700189 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700190 id = greenland::IntrinsicHelper::ConstObj;
191 } else {
192 id = greenland::IntrinsicHelper::ConstInt;
193 }
194 }
195 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
196 return cUnit->irb->CreateCall(intr, src);
197}
buzbeeb03f4872012-06-11 15:22:11 -0700198
199void emitPopShadowFrame(CompilationUnit* cUnit)
200{
201 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
202 greenland::IntrinsicHelper::PopShadowFrame);
203 cUnit->irb->CreateCall(intr);
204}
205
buzbee2cfc6392012-05-07 14:51:40 -0700206llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
207 RegLocation loc)
208{
209 greenland::IntrinsicHelper::IntrinsicId id;
210 if (loc.wide) {
211 if (loc.fp) {
212 id = greenland::IntrinsicHelper::CopyDouble;
213 } else {
214 id = greenland::IntrinsicHelper::CopyLong;
215 }
216 } else {
217 if (loc.fp) {
218 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700219 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700220 id = greenland::IntrinsicHelper::CopyObj;
221 } else {
222 id = greenland::IntrinsicHelper::CopyInt;
223 }
224 }
225 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
226 return cUnit->irb->CreateCall(intr, src);
227}
228
buzbee32412962012-06-26 16:27:56 -0700229void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
230{
231 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
232 greenland::IntrinsicHelper::GetException);
233 llvm::Value* res = cUnit->irb->CreateCall(func);
234 defineValue(cUnit, res, rlDest.origSReg);
235}
236
237void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
238{
239 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
240 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
241 greenland::IntrinsicHelper::Throw);
242 cUnit->irb->CreateCall(func, src);
243 cUnit->irb->CreateUnreachable();
244}
245
buzbee8fa0fda2012-06-27 15:44:52 -0700246void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
247 greenland::IntrinsicHelper::IntrinsicId id,
248 RegLocation rlSrc)
249{
250 llvm::SmallVector<llvm::Value*, 2> args;
251 args.push_back(cUnit->irb->getInt32(optFlags));
252 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
253 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
254 cUnit->irb->CreateCall(func, args);
255}
256
257void convertArrayLength(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
258{
259 llvm::SmallVector<llvm::Value*, 2> args;
260 args.push_back(cUnit->irb->getInt32(optFlags));
261 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
262 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
263 greenland::IntrinsicHelper::ArrayLength);
264 cUnit->irb->CreateCall(func, args);
265}
266
buzbee32412962012-06-26 16:27:56 -0700267void convertThrowVerificationError(CompilationUnit* cUnit, int info1, int info2)
268{
269 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
270 greenland::IntrinsicHelper::Throw);
271 llvm::SmallVector<llvm::Value*, 2> args;
272 args.push_back(cUnit->irb->getInt32(info1));
273 args.push_back(cUnit->irb->getInt32(info2));
274 cUnit->irb->CreateCall(func, args);
275 cUnit->irb->CreateUnreachable();
276}
277
buzbee2cfc6392012-05-07 14:51:40 -0700278void emitSuspendCheck(CompilationUnit* cUnit)
279{
280 greenland::IntrinsicHelper::IntrinsicId id =
281 greenland::IntrinsicHelper::CheckSuspend;
282 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
283 cUnit->irb->CreateCall(intr);
284}
285
286llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
287 llvm::Value* src1, llvm::Value* src2)
288{
289 llvm::Value* res = NULL;
290 switch(cc) {
291 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
292 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
293 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
294 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
295 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
296 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
297 default: LOG(FATAL) << "Unexpected cc value " << cc;
298 }
299 return res;
300}
301
302void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
303 ConditionCode cc, RegLocation rlSrc1,
304 RegLocation rlSrc2)
305{
306 if (bb->taken->startOffset <= mir->offset) {
307 emitSuspendCheck(cUnit);
308 }
309 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
310 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
311 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
312 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
313 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
314 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700315 // Don't redo the fallthrough branch in the BB driver
316 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700317}
318
319void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
320 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
321{
322 if (bb->taken->startOffset <= mir->offset) {
323 emitSuspendCheck(cUnit);
324 }
325 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
326 llvm::Value* src2;
327 if (rlSrc1.ref) {
328 src2 = cUnit->irb->GetJNull();
329 } else {
330 src2 = cUnit->irb->getInt32(0);
331 }
332 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
333 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
334 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
335 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700336 // Don't redo the fallthrough branch in the BB driver
337 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700338}
339
340llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
341 llvm::Value* src1, llvm::Value* src2)
342{
343 greenland::IntrinsicHelper::IntrinsicId id;
344 if (isLong) {
345 if (isDiv) {
346 id = greenland::IntrinsicHelper::DivLong;
347 } else {
348 id = greenland::IntrinsicHelper::RemLong;
349 }
350 } else if (isDiv) {
351 id = greenland::IntrinsicHelper::DivInt;
352 } else {
353 id = greenland::IntrinsicHelper::RemInt;
354 }
355 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
356 llvm::SmallVector<llvm::Value*, 2>args;
357 args.push_back(src1);
358 args.push_back(src2);
359 return cUnit->irb->CreateCall(intr, args);
360}
361
362llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
363 llvm::Value* src1, llvm::Value* src2)
364{
365 llvm::Value* res = NULL;
366 switch(op) {
367 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
368 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700369 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700370 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
371 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
372 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
373 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
374 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
375 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700376 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
377 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
378 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700379 default:
380 LOG(FATAL) << "Invalid op " << op;
381 }
382 return res;
383}
384
385void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
386 RegLocation rlSrc1, RegLocation rlSrc2)
387{
388 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
389 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
390 llvm::Value* res = NULL;
391 switch(op) {
392 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
393 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
394 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
395 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
396 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
397 default:
398 LOG(FATAL) << "Invalid op " << op;
399 }
400 defineValue(cUnit, res, rlDest.origSReg);
401}
402
buzbee4f1181f2012-06-22 13:52:12 -0700403void convertShift(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
404 RegLocation rlSrc1, RegLocation rlSrc2)
405{
406 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
buzbee101305f2012-06-28 18:00:56 -0700407 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
408 /*
409 * TODO: Figure out how best to handle constraining the shift
410 * amount to 31 for int and 63 for long. We take care of this
411 * inline for int and in the out-of-line handler for longs, so
412 * it's a bit of a waste to generate llvm bitcode for this.
413 * Yet more intrinsics?
414 */
415 UNIMPLEMENTED(WARNING) << "llvm shift mismatch";
buzbee4f1181f2012-06-22 13:52:12 -0700416 if (rlDest.wide) {
buzbee101305f2012-06-28 18:00:56 -0700417 // llvm thinks the shift could should be in 64 bits.
418 src2 = cUnit->irb->CreateZExt(src2, cUnit->irb->getInt64Ty());
buzbee4f1181f2012-06-22 13:52:12 -0700419 }
buzbee101305f2012-06-28 18:00:56 -0700420 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
buzbee4f1181f2012-06-22 13:52:12 -0700421 defineValue(cUnit, res, rlDest.origSReg);
422}
423
buzbee2cfc6392012-05-07 14:51:40 -0700424void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
425 RegLocation rlSrc1, RegLocation rlSrc2)
426{
427 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
428 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
429 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
430 defineValue(cUnit, res, rlDest.origSReg);
431}
432
buzbeeb03f4872012-06-11 15:22:11 -0700433void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
434{
435 int index = -1;
436 DCHECK(newVal != NULL);
437 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
438 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
439 if (cUnit->shadowMap[i] == vReg) {
440 index = i;
441 break;
442 }
443 }
Elliott Hughes74847412012-06-20 18:10:21 -0700444 DCHECK_NE(index, -1) << "Corrupt shadowMap";
buzbeeb03f4872012-06-11 15:22:11 -0700445 greenland::IntrinsicHelper::IntrinsicId id =
446 greenland::IntrinsicHelper::SetShadowFrameEntry;
447 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
448 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
449 llvm::Value* args[] = { newVal, tableSlot };
450 cUnit->irb->CreateCall(func, args);
451}
452
buzbee2cfc6392012-05-07 14:51:40 -0700453void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
454 RegLocation rlSrc1, int32_t imm)
455{
456 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
457 llvm::Value* src2 = cUnit->irb->getInt32(imm);
458 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
459 defineValue(cUnit, res, rlDest.origSReg);
460}
461
buzbee101305f2012-06-28 18:00:56 -0700462/*
463 * Process arguments for invoke. Note: this code is also used to
464 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
465 * The requirements are similar.
466 */
buzbee6969d502012-06-15 16:40:31 -0700467void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee101305f2012-06-28 18:00:56 -0700468 InvokeType invokeType, bool isRange, bool isNewArray)
buzbee6969d502012-06-15 16:40:31 -0700469{
470 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
471 llvm::SmallVector<llvm::Value*, 10> args;
472 // Insert the invokeType
473 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
474 // Insert the method_idx
475 args.push_back(cUnit->irb->getInt32(info->index));
476 // Insert the optimization flags
477 args.push_back(cUnit->irb->getInt32(info->optFlags));
478 // Now, insert the actual arguments
479 if (cUnit->printMe) {
480 LOG(INFO) << "Building Invoke info";
481 }
482 for (int i = 0; i < info->numArgWords;) {
483 if (cUnit->printMe) {
484 oatDumpRegLoc(info->args[i]);
485 }
486 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
487 args.push_back(val);
488 i += info->args[i].wide ? 2 : 1;
489 }
490 /*
491 * Choose the invoke return type based on actual usage. Note: may
492 * be different than shorty. For example, if a function return value
493 * is not used, we'll treat this as a void invoke.
494 */
495 greenland::IntrinsicHelper::IntrinsicId id;
buzbee101305f2012-06-28 18:00:56 -0700496 if (isNewArray) {
497 id = greenland::IntrinsicHelper::NewArray;
498 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700499 id = greenland::IntrinsicHelper::HLInvokeVoid;
500 } else {
501 if (info->result.wide) {
502 if (info->result.fp) {
503 id = greenland::IntrinsicHelper::HLInvokeDouble;
504 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700505 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700506 }
507 } else if (info->result.ref) {
508 id = greenland::IntrinsicHelper::HLInvokeObj;
509 } else if (info->result.fp) {
510 id = greenland::IntrinsicHelper::HLInvokeFloat;
511 } else {
512 id = greenland::IntrinsicHelper::HLInvokeInt;
513 }
514 }
515 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
516 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
517 if (info->result.location != kLocInvalid) {
518 defineValue(cUnit, res, info->result.origSReg);
519 }
520}
521
buzbee101305f2012-06-28 18:00:56 -0700522void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
523 greenland::IntrinsicHelper::IntrinsicId id,
524 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700525{
buzbee6969d502012-06-15 16:40:31 -0700526 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700527 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700528 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
529 defineValue(cUnit, res, rlDest.origSReg);
530}
531
buzbee101305f2012-06-28 18:00:56 -0700532void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
533 RegLocation rlSrc)
534{
535 greenland::IntrinsicHelper::IntrinsicId id;
536 id = greenland::IntrinsicHelper::CheckCast;
537 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
538 llvm::SmallVector<llvm::Value*, 2> args;
539 args.push_back(cUnit->irb->getInt32(type_idx));
540 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
541 cUnit->irb->CreateCall(intr, args);
542}
543
buzbee8fa0fda2012-06-27 15:44:52 -0700544void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
545 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700546{
547 greenland::IntrinsicHelper::IntrinsicId id;
548 id = greenland::IntrinsicHelper::NewInstance;
549 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
550 llvm::Value* index = cUnit->irb->getInt32(type_idx);
551 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
552 defineValue(cUnit, res, rlDest.origSReg);
553}
554
buzbee8fa0fda2012-06-27 15:44:52 -0700555void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
556 RegLocation rlDest, RegLocation rlSrc)
557{
558 greenland::IntrinsicHelper::IntrinsicId id;
559 id = greenland::IntrinsicHelper::NewArray;
560 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
561 llvm::SmallVector<llvm::Value*, 2> args;
562 args.push_back(cUnit->irb->getInt32(type_idx));
563 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
564 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
565 defineValue(cUnit, res, rlDest.origSReg);
566}
567
568void convertAget(CompilationUnit* cUnit, int optFlags,
569 greenland::IntrinsicHelper::IntrinsicId id,
570 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
571{
572 llvm::SmallVector<llvm::Value*, 3> args;
573 args.push_back(cUnit->irb->getInt32(optFlags));
574 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
575 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
576 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
577 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
578 defineValue(cUnit, res, rlDest.origSReg);
579}
580
581void convertAput(CompilationUnit* cUnit, int optFlags,
582 greenland::IntrinsicHelper::IntrinsicId id,
583 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
584{
585 llvm::SmallVector<llvm::Value*, 4> args;
586 args.push_back(cUnit->irb->getInt32(optFlags));
587 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
588 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
589 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
590 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
591 cUnit->irb->CreateCall(intr, args);
592}
593
buzbee101305f2012-06-28 18:00:56 -0700594void convertIget(CompilationUnit* cUnit, int optFlags,
595 greenland::IntrinsicHelper::IntrinsicId id,
596 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
597{
598 llvm::SmallVector<llvm::Value*, 3> args;
599 args.push_back(cUnit->irb->getInt32(optFlags));
600 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
601 args.push_back(cUnit->irb->getInt32(fieldIndex));
602 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
603 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
604 defineValue(cUnit, res, rlDest.origSReg);
605}
606
607void convertIput(CompilationUnit* cUnit, int optFlags,
608 greenland::IntrinsicHelper::IntrinsicId id,
609 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
610{
611 llvm::SmallVector<llvm::Value*, 4> args;
612 args.push_back(cUnit->irb->getInt32(optFlags));
613 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
614 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
615 args.push_back(cUnit->irb->getInt32(fieldIndex));
616 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
617 cUnit->irb->CreateCall(intr, args);
618}
619
buzbee8fa0fda2012-06-27 15:44:52 -0700620void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
621 RegLocation rlDest, RegLocation rlSrc)
622{
623 greenland::IntrinsicHelper::IntrinsicId id;
624 id = greenland::IntrinsicHelper::InstanceOf;
625 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
626 llvm::SmallVector<llvm::Value*, 2> args;
627 args.push_back(cUnit->irb->getInt32(type_idx));
628 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
629 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
630 defineValue(cUnit, res, rlDest.origSReg);
631}
632
buzbee101305f2012-06-28 18:00:56 -0700633void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
634 RegLocation rlSrc)
635{
636 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
637 cUnit->irb->getInt64Ty());
638 defineValue(cUnit, res, rlDest.origSReg);
639}
640
641void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
642 RegLocation rlSrc,
643 greenland::IntrinsicHelper::IntrinsicId id)
644{
645 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
646 llvm::Value* res = cUnit->irb->CreateCall(intr,
647 getLLVMValue(cUnit, rlSrc.origSReg));
648 defineValue(cUnit, res, rlDest.origSReg);
649}
650
buzbee2cfc6392012-05-07 14:51:40 -0700651/*
652 * Target-independent code generation. Use only high-level
653 * load/store utilities here, or target-dependent genXX() handlers
654 * when necessary.
655 */
656bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
657 llvm::BasicBlock* llvmBB, LIR* labelList)
658{
659 bool res = false; // Assume success
660 RegLocation rlSrc[3];
661 RegLocation rlDest = badLoc;
662 RegLocation rlResult = badLoc;
663 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee32412962012-06-26 16:27:56 -0700664 uint32_t vA = mir->dalvikInsn.vA;
buzbee6969d502012-06-15 16:40:31 -0700665 uint32_t vB = mir->dalvikInsn.vB;
666 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700667 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700668
buzbeeb03f4872012-06-11 15:22:11 -0700669 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700670
671 /* Prep Src and Dest locations */
672 int nextSreg = 0;
673 int nextLoc = 0;
674 int attrs = oatDataFlowAttributes[opcode];
675 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
676 if (attrs & DF_UA) {
677 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700678 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700679 nextSreg+= 2;
680 } else {
681 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
682 nextSreg++;
683 }
684 }
685 if (attrs & DF_UB) {
686 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700687 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700688 nextSreg+= 2;
689 } else {
690 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
691 nextSreg++;
692 }
693 }
694 if (attrs & DF_UC) {
695 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700696 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700697 } else {
698 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
699 }
700 }
701 if (attrs & DF_DA) {
702 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700703 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700704 } else {
buzbee15bf9802012-06-12 17:49:27 -0700705 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700706 if (rlDest.ref) {
707 objectDefinition = true;
708 }
buzbee2cfc6392012-05-07 14:51:40 -0700709 }
710 }
711
712 switch (opcode) {
713 case Instruction::NOP:
714 break;
715
716 case Instruction::MOVE:
717 case Instruction::MOVE_OBJECT:
718 case Instruction::MOVE_16:
719 case Instruction::MOVE_OBJECT_16:
720 case Instruction::MOVE_FROM16:
721 case Instruction::MOVE_WIDE:
722 case Instruction::MOVE_WIDE_16:
723 case Instruction::MOVE_WIDE_FROM16: {
724 /*
725 * Moves/copies are meaningless in pure SSA register form,
726 * but we need to preserve them for the conversion back into
727 * MIR (at least until we stop using the Dalvik register maps).
728 * Insert a dummy intrinsic copy call, which will be recognized
729 * by the quick path and removed by the portable path.
730 */
731 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
732 llvm::Value* res = emitCopy(cUnit, src, rlDest);
733 defineValue(cUnit, res, rlDest.origSReg);
734 }
735 break;
736
737 case Instruction::CONST:
738 case Instruction::CONST_4:
739 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700740 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700741 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
742 defineValue(cUnit, res, rlDest.origSReg);
743 }
744 break;
745
746 case Instruction::CONST_WIDE_16:
747 case Instruction::CONST_WIDE_32: {
buzbee6969d502012-06-15 16:40:31 -0700748 llvm::Constant* immValue = cUnit->irb->GetJLong(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700749 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
750 defineValue(cUnit, res, rlDest.origSReg);
751 }
752 break;
753
754 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700755 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700756 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
757 defineValue(cUnit, res, rlDest.origSReg);
758 }
759 break;
760
761 case Instruction::CONST_WIDE: {
762 llvm::Constant* immValue =
763 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
764 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
765 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700766 }
767 break;
buzbee2cfc6392012-05-07 14:51:40 -0700768 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700769 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700770 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
771 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
772 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700773 }
774 break;
775
buzbee8fa0fda2012-06-27 15:44:52 -0700776 case Instruction::SPUT_OBJECT:
777 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
778 rlSrc[0]);
779 break;
780 case Instruction::SPUT:
781 if (rlSrc[0].fp) {
782 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
783 rlSrc[0]);
784 } else {
785 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
786 }
787 break;
788 case Instruction::SPUT_BOOLEAN:
789 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
790 rlSrc[0]);
791 break;
792 case Instruction::SPUT_BYTE:
793 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
794 break;
795 case Instruction::SPUT_CHAR:
796 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
797 break;
798 case Instruction::SPUT_SHORT:
799 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
800 break;
801 case Instruction::SPUT_WIDE:
802 if (rlSrc[0].fp) {
803 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
804 rlSrc[0]);
805 } else {
806 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
807 rlSrc[0]);
808 }
809 break;
810
811 case Instruction::SGET_OBJECT:
812 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
813 break;
814 case Instruction::SGET:
815 if (rlDest.fp) {
816 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
817 } else {
818 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
819 }
820 break;
821 case Instruction::SGET_BOOLEAN:
822 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
823 break;
824 case Instruction::SGET_BYTE:
825 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
826 break;
827 case Instruction::SGET_CHAR:
828 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
829 break;
830 case Instruction::SGET_SHORT:
831 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
832 break;
833 case Instruction::SGET_WIDE:
834 if (rlDest.fp) {
835 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
836 rlDest);
837 } else {
838 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -0700839 }
840 break;
buzbee2cfc6392012-05-07 14:51:40 -0700841
842 case Instruction::RETURN_WIDE:
843 case Instruction::RETURN:
844 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -0700845 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700846 emitSuspendCheck(cUnit);
847 }
buzbeeb03f4872012-06-11 15:22:11 -0700848 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700849 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
850 bb->hasReturn = true;
851 }
852 break;
853
854 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -0700855 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700856 emitSuspendCheck(cUnit);
857 }
buzbeeb03f4872012-06-11 15:22:11 -0700858 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700859 cUnit->irb->CreateRetVoid();
860 bb->hasReturn = true;
861 }
862 break;
863
864 case Instruction::IF_EQ:
865 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
866 break;
867 case Instruction::IF_NE:
868 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
869 break;
870 case Instruction::IF_LT:
871 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
872 break;
873 case Instruction::IF_GE:
874 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
875 break;
876 case Instruction::IF_GT:
877 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
878 break;
879 case Instruction::IF_LE:
880 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
881 break;
882 case Instruction::IF_EQZ:
883 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
884 break;
885 case Instruction::IF_NEZ:
886 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
887 break;
888 case Instruction::IF_LTZ:
889 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
890 break;
891 case Instruction::IF_GEZ:
892 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
893 break;
894 case Instruction::IF_GTZ:
895 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
896 break;
897 case Instruction::IF_LEZ:
898 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
899 break;
900
901 case Instruction::GOTO:
902 case Instruction::GOTO_16:
903 case Instruction::GOTO_32: {
904 if (bb->taken->startOffset <= bb->startOffset) {
905 emitSuspendCheck(cUnit);
906 }
907 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
908 }
909 break;
910
911 case Instruction::ADD_LONG:
912 case Instruction::ADD_LONG_2ADDR:
913 case Instruction::ADD_INT:
914 case Instruction::ADD_INT_2ADDR:
915 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
916 break;
917 case Instruction::SUB_LONG:
918 case Instruction::SUB_LONG_2ADDR:
919 case Instruction::SUB_INT:
920 case Instruction::SUB_INT_2ADDR:
921 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
922 break;
923 case Instruction::MUL_LONG:
924 case Instruction::MUL_LONG_2ADDR:
925 case Instruction::MUL_INT:
926 case Instruction::MUL_INT_2ADDR:
927 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
928 break;
929 case Instruction::DIV_LONG:
930 case Instruction::DIV_LONG_2ADDR:
931 case Instruction::DIV_INT:
932 case Instruction::DIV_INT_2ADDR:
933 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
934 break;
935 case Instruction::REM_LONG:
936 case Instruction::REM_LONG_2ADDR:
937 case Instruction::REM_INT:
938 case Instruction::REM_INT_2ADDR:
939 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
940 break;
941 case Instruction::AND_LONG:
942 case Instruction::AND_LONG_2ADDR:
943 case Instruction::AND_INT:
944 case Instruction::AND_INT_2ADDR:
945 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
946 break;
947 case Instruction::OR_LONG:
948 case Instruction::OR_LONG_2ADDR:
949 case Instruction::OR_INT:
950 case Instruction::OR_INT_2ADDR:
951 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
952 break;
953 case Instruction::XOR_LONG:
954 case Instruction::XOR_LONG_2ADDR:
955 case Instruction::XOR_INT:
956 case Instruction::XOR_INT_2ADDR:
957 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
958 break;
959 case Instruction::SHL_LONG:
960 case Instruction::SHL_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700961 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
962 break;
buzbee2cfc6392012-05-07 14:51:40 -0700963 case Instruction::SHL_INT:
964 case Instruction::SHL_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700965 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -0700966 break;
967 case Instruction::SHR_LONG:
968 case Instruction::SHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700969 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
970 break;
buzbee2cfc6392012-05-07 14:51:40 -0700971 case Instruction::SHR_INT:
972 case Instruction::SHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700973 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -0700974 break;
975 case Instruction::USHR_LONG:
976 case Instruction::USHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700977 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
978 break;
buzbee2cfc6392012-05-07 14:51:40 -0700979 case Instruction::USHR_INT:
980 case Instruction::USHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700981 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -0700982 break;
983
984 case Instruction::ADD_INT_LIT16:
985 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700986 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700987 break;
988 case Instruction::RSUB_INT:
989 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700990 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700991 break;
992 case Instruction::MUL_INT_LIT16:
993 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700994 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700995 break;
996 case Instruction::DIV_INT_LIT16:
997 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700998 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700999 break;
1000 case Instruction::REM_INT_LIT16:
1001 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001002 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001003 break;
1004 case Instruction::AND_INT_LIT16:
1005 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001006 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001007 break;
1008 case Instruction::OR_INT_LIT16:
1009 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001010 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001011 break;
1012 case Instruction::XOR_INT_LIT16:
1013 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001014 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001015 break;
1016 case Instruction::SHL_INT_LIT8:
buzbee4f1181f2012-06-22 13:52:12 -07001017 convertArithOpLit(cUnit, kOpLsl, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001018 break;
1019 case Instruction::SHR_INT_LIT8:
buzbee101305f2012-06-28 18:00:56 -07001020 convertArithOpLit(cUnit, kOpAsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001021 break;
1022 case Instruction::USHR_INT_LIT8:
buzbee101305f2012-06-28 18:00:56 -07001023 convertArithOpLit(cUnit, kOpLsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001024 break;
1025
1026 case Instruction::ADD_FLOAT:
1027 case Instruction::ADD_FLOAT_2ADDR:
1028 case Instruction::ADD_DOUBLE:
1029 case Instruction::ADD_DOUBLE_2ADDR:
1030 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1031 break;
1032
1033 case Instruction::SUB_FLOAT:
1034 case Instruction::SUB_FLOAT_2ADDR:
1035 case Instruction::SUB_DOUBLE:
1036 case Instruction::SUB_DOUBLE_2ADDR:
1037 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1038 break;
1039
1040 case Instruction::MUL_FLOAT:
1041 case Instruction::MUL_FLOAT_2ADDR:
1042 case Instruction::MUL_DOUBLE:
1043 case Instruction::MUL_DOUBLE_2ADDR:
1044 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1045 break;
1046
1047 case Instruction::DIV_FLOAT:
1048 case Instruction::DIV_FLOAT_2ADDR:
1049 case Instruction::DIV_DOUBLE:
1050 case Instruction::DIV_DOUBLE_2ADDR:
1051 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1052 break;
1053
1054 case Instruction::REM_FLOAT:
1055 case Instruction::REM_FLOAT_2ADDR:
1056 case Instruction::REM_DOUBLE:
1057 case Instruction::REM_DOUBLE_2ADDR:
1058 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1059 break;
1060
buzbee6969d502012-06-15 16:40:31 -07001061 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001062 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1063 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001064 break;
1065 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001066 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1067 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001068 break;
1069
1070 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001071 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1072 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001073 break;
1074 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001075 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1076 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001077 break;
1078
1079 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001080 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1081 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001082 break;
1083 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001084 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1085 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001086 break;
1087
1088 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001089 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1090 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001091 break;
1092 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001093 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1094 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001095 break;
1096
1097 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001098 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1099 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001100 break;
1101 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001102 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1103 false /* NewFilledArray */);
1104 break;
1105 case Instruction::FILLED_NEW_ARRAY:
1106 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1107 true /* NewFilledArray */);
1108 break;
1109 case Instruction::FILLED_NEW_ARRAY_RANGE:
1110 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1111 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001112 break;
1113
1114 case Instruction::CONST_STRING:
1115 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001116 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1117 rlDest);
1118 break;
1119
1120 case Instruction::CONST_CLASS:
1121 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1122 rlDest);
1123 break;
1124
1125 case Instruction::CHECK_CAST:
1126 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001127 break;
1128
buzbee4f1181f2012-06-22 13:52:12 -07001129 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001130 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001131 break;
1132
buzbee32412962012-06-26 16:27:56 -07001133 case Instruction::MOVE_EXCEPTION:
1134 convertMoveException(cUnit, rlDest);
1135 break;
1136
1137 case Instruction::THROW:
1138 convertThrow(cUnit, rlSrc[0]);
1139 break;
1140
1141 case Instruction::THROW_VERIFICATION_ERROR:
1142 convertThrowVerificationError(cUnit, vA, vB);
1143 break;
buzbee6969d502012-06-15 16:40:31 -07001144
buzbee2cfc6392012-05-07 14:51:40 -07001145 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001146 case Instruction::MOVE_RESULT:
1147 case Instruction::MOVE_RESULT_OBJECT:
buzbee8fa0fda2012-06-27 15:44:52 -07001148 CHECK(false) << "Unexpected MOVE_RESULT";
buzbee2cfc6392012-05-07 14:51:40 -07001149 break;
1150
1151 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001152 convertMonitorEnterExit(cUnit, optFlags,
1153 greenland::IntrinsicHelper::MonitorEnter,
1154 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001155 break;
1156
1157 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001158 convertMonitorEnterExit(cUnit, optFlags,
1159 greenland::IntrinsicHelper::MonitorExit,
1160 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001161 break;
1162
1163 case Instruction::ARRAY_LENGTH:
buzbee8fa0fda2012-06-27 15:44:52 -07001164 convertArrayLength(cUnit, optFlags, rlSrc[0]);
1165 break;
1166
1167 case Instruction::NEW_ARRAY:
1168 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1169 break;
1170
1171 case Instruction::INSTANCE_OF:
1172 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1173 break;
1174
1175 case Instruction::AGET:
1176 if (rlDest.fp) {
1177 convertAget(cUnit, optFlags,
1178 greenland::IntrinsicHelper::HLArrayGetFloat,
1179 rlDest, rlSrc[0], rlSrc[1]);
1180 } else {
1181 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1182 rlDest, rlSrc[0], rlSrc[1]);
1183 }
1184 break;
1185 case Instruction::AGET_OBJECT:
1186 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1187 rlDest, rlSrc[0], rlSrc[1]);
1188 break;
1189 case Instruction::AGET_BOOLEAN:
1190 convertAget(cUnit, optFlags,
1191 greenland::IntrinsicHelper::HLArrayGetBoolean,
1192 rlDest, rlSrc[0], rlSrc[1]);
1193 break;
1194 case Instruction::AGET_BYTE:
1195 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1196 rlDest, rlSrc[0], rlSrc[1]);
1197 break;
1198 case Instruction::AGET_CHAR:
1199 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1200 rlDest, rlSrc[0], rlSrc[1]);
1201 break;
1202 case Instruction::AGET_SHORT:
1203 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1204 rlDest, rlSrc[0], rlSrc[1]);
1205 break;
1206 case Instruction::AGET_WIDE:
1207 if (rlDest.fp) {
1208 convertAget(cUnit, optFlags,
1209 greenland::IntrinsicHelper::HLArrayGetDouble,
1210 rlDest, rlSrc[0], rlSrc[1]);
1211 } else {
1212 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1213 rlDest, rlSrc[0], rlSrc[1]);
1214 }
1215 break;
1216
1217 case Instruction::APUT:
1218 if (rlSrc[0].fp) {
1219 convertAput(cUnit, optFlags,
1220 greenland::IntrinsicHelper::HLArrayPutFloat,
1221 rlSrc[0], rlSrc[1], rlSrc[2]);
1222 } else {
1223 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1224 rlSrc[0], rlSrc[1], rlSrc[2]);
1225 }
1226 break;
1227 case Instruction::APUT_OBJECT:
1228 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1229 rlSrc[0], rlSrc[1], rlSrc[2]);
1230 break;
1231 case Instruction::APUT_BOOLEAN:
1232 convertAput(cUnit, optFlags,
1233 greenland::IntrinsicHelper::HLArrayPutBoolean,
1234 rlSrc[0], rlSrc[1], rlSrc[2]);
1235 break;
1236 case Instruction::APUT_BYTE:
1237 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1238 rlSrc[0], rlSrc[1], rlSrc[2]);
1239 break;
1240 case Instruction::APUT_CHAR:
1241 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1242 rlSrc[0], rlSrc[1], rlSrc[2]);
1243 break;
1244 case Instruction::APUT_SHORT:
1245 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1246 rlSrc[0], rlSrc[1], rlSrc[2]);
1247 break;
1248 case Instruction::APUT_WIDE:
1249 if (rlSrc[0].fp) {
1250 convertAput(cUnit, optFlags,
1251 greenland::IntrinsicHelper::HLArrayPutDouble,
1252 rlSrc[0], rlSrc[1], rlSrc[2]);
1253 } else {
1254 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1255 rlSrc[0], rlSrc[1], rlSrc[2]);
1256 }
1257 break;
1258
buzbee101305f2012-06-28 18:00:56 -07001259 case Instruction::IGET:
1260 if (rlDest.fp) {
1261 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
1262 rlSrc[0], rlSrc[1], vC);
1263 } else {
1264 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
1265 rlSrc[0], rlSrc[1], vC);
1266 }
buzbee2cfc6392012-05-07 14:51:40 -07001267 break;
buzbee101305f2012-06-28 18:00:56 -07001268 case Instruction::IGET_OBJECT:
1269 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
1270 rlSrc[0], rlSrc[1], vC);
1271 break;
1272 case Instruction::IGET_BOOLEAN:
1273 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
1274 rlSrc[0], rlSrc[1], vC);
1275 break;
1276 case Instruction::IGET_BYTE:
1277 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
1278 rlSrc[0], rlSrc[1], vC);
1279 break;
1280 case Instruction::IGET_CHAR:
1281 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
1282 rlSrc[0], rlSrc[1], vC);
1283 break;
1284 case Instruction::IGET_SHORT:
1285 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
1286 rlSrc[0], rlSrc[1], vC);
1287 break;
1288 case Instruction::IGET_WIDE:
1289 if (rlDest.fp) {
1290 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
1291 rlSrc[0], rlSrc[1], vC);
1292 } else {
1293 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
1294 rlSrc[0], rlSrc[1], vC);
1295 }
1296 break;
1297 case Instruction::IPUT:
1298 if (rlDest.fp) {
1299 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1300 rlSrc[0], rlSrc[1], vC);
1301 } else {
1302 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1303 rlSrc[0], rlSrc[1], vC);
1304 }
1305 break;
1306 case Instruction::IPUT_OBJECT:
1307 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1308 rlSrc[0], rlSrc[1], vC);
1309 break;
1310 case Instruction::IPUT_BOOLEAN:
1311 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1312 rlSrc[0], rlSrc[1], vC);
1313 break;
1314 case Instruction::IPUT_BYTE:
1315 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1316 rlSrc[0], rlSrc[1], vC);
1317 break;
1318 case Instruction::IPUT_CHAR:
1319 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1320 rlSrc[0], rlSrc[1], vC);
1321 break;
1322 case Instruction::IPUT_SHORT:
1323 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1324 rlSrc[0], rlSrc[1], vC);
1325 break;
1326 case Instruction::IPUT_WIDE:
1327 if (rlDest.fp) {
1328 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1329 rlSrc[0], rlSrc[1], vC);
1330 } else {
1331 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1332 rlSrc[0], rlSrc[1], vC);
1333 }
buzbee2cfc6392012-05-07 14:51:40 -07001334 break;
1335
1336 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001337 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001338 break;
1339
buzbee101305f2012-06-28 18:00:56 -07001340 case Instruction::INT_TO_LONG:
1341 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001342 break;
1343
buzbee101305f2012-06-28 18:00:56 -07001344 case Instruction::INT_TO_CHAR:
1345 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1346 greenland::IntrinsicHelper::IntToChar);
1347 break;
1348 case Instruction::INT_TO_BYTE:
1349 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1350 greenland::IntrinsicHelper::IntToByte);
1351 break;
1352 case Instruction::INT_TO_SHORT:
1353 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1354 greenland::IntrinsicHelper::IntToShort);
1355 break;
1356
1357#if 0
1358
buzbee2cfc6392012-05-07 14:51:40 -07001359 case Instruction::PACKED_SWITCH:
1360 genPackedSwitch(cUnit, mir, rlSrc[0]);
1361 break;
1362
1363 case Instruction::SPARSE_SWITCH:
1364 genSparseSwitch(cUnit, mir, rlSrc[0], labelList);
1365 break;
1366
1367 case Instruction::CMPL_FLOAT:
1368 case Instruction::CMPG_FLOAT:
1369 case Instruction::CMPL_DOUBLE:
1370 case Instruction::CMPG_DOUBLE:
1371 res = genCmpFP(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
1372 break;
1373
1374 case Instruction::CMP_LONG:
1375 genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
1376 break;
1377
buzbee2cfc6392012-05-07 14:51:40 -07001378 case Instruction::NEG_INT:
1379 case Instruction::NOT_INT:
1380 res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1381 break;
1382
1383 case Instruction::NEG_LONG:
1384 case Instruction::NOT_LONG:
1385 res = genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1386 break;
1387
1388 case Instruction::NEG_FLOAT:
1389 res = genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1390 break;
1391
1392 case Instruction::NEG_DOUBLE:
1393 res = genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1394 break;
1395
buzbee2cfc6392012-05-07 14:51:40 -07001396 case Instruction::LONG_TO_INT:
1397 rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
1398 rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
1399 storeValue(cUnit, rlDest, rlSrc[0]);
1400 break;
1401
buzbee2cfc6392012-05-07 14:51:40 -07001402 case Instruction::INT_TO_FLOAT:
1403 case Instruction::INT_TO_DOUBLE:
1404 case Instruction::LONG_TO_FLOAT:
1405 case Instruction::LONG_TO_DOUBLE:
1406 case Instruction::FLOAT_TO_INT:
1407 case Instruction::FLOAT_TO_LONG:
1408 case Instruction::FLOAT_TO_DOUBLE:
1409 case Instruction::DOUBLE_TO_INT:
1410 case Instruction::DOUBLE_TO_LONG:
1411 case Instruction::DOUBLE_TO_FLOAT:
1412 genConversion(cUnit, mir);
1413 break;
1414
1415#endif
1416
1417 default:
buzbee32412962012-06-26 16:27:56 -07001418 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001419 res = true;
1420 }
buzbeeb03f4872012-06-11 15:22:11 -07001421 if (objectDefinition) {
1422 setShadowFrameEntry(cUnit, (llvm::Value*)
1423 cUnit->llvmValues.elemList[rlDest.origSReg]);
1424 }
buzbee2cfc6392012-05-07 14:51:40 -07001425 return res;
1426}
1427
1428/* Extended MIR instructions like PHI */
1429void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1430 llvm::BasicBlock* llvmBB)
1431{
1432
1433 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1434 case kMirOpPhi: {
1435 int* incoming = (int*)mir->dalvikInsn.vB;
1436 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
1437 llvm::Type* phiType =
1438 llvmTypeFromLocRec(cUnit, rlDest);
1439 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1440 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1441 RegLocation loc;
1442 if (rlDest.wide) {
buzbee15bf9802012-06-12 17:49:27 -07001443 loc = oatGetSrcWide(cUnit, mir, i);
buzbee2cfc6392012-05-07 14:51:40 -07001444 i++;
1445 } else {
1446 loc = oatGetSrc(cUnit, mir, i);
1447 }
1448 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
1449 getLLVMBlock(cUnit, incoming[i]));
1450 }
1451 defineValue(cUnit, phi, rlDest.origSReg);
1452 break;
1453 }
1454 case kMirOpCopy: {
1455 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1456 break;
1457 }
1458#if defined(TARGET_ARM)
1459 case kMirOpFusedCmplFloat:
1460 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1461 break;
1462 case kMirOpFusedCmpgFloat:
1463 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1464 break;
1465 case kMirOpFusedCmplDouble:
1466 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1467 break;
1468 case kMirOpFusedCmpgDouble:
1469 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1470 break;
1471 case kMirOpFusedCmpLong:
1472 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1473 break;
1474#endif
1475 default:
1476 break;
1477 }
1478}
1479
1480void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1481{
1482 cUnit->currentDalvikOffset = offset;
1483 llvm::SmallVector<llvm::Value*, 1>arrayRef;
1484 arrayRef.push_back(cUnit->irb->getInt32(offset));
1485 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1486 cUnit->irb->SetDexOffset(node);
1487}
1488
1489// Attach method info as metadata to special intrinsic
1490void setMethodInfo(CompilationUnit* cUnit)
1491{
1492 // We don't want dex offset on this
1493 cUnit->irb->SetDexOffset(NULL);
1494 greenland::IntrinsicHelper::IntrinsicId id;
1495 id = greenland::IntrinsicHelper::MethodInfo;
1496 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1497 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1498 llvm::SmallVector<llvm::Value*, 2> regInfo;
1499 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1500 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1501 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1502 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1503 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1504 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1505 inst->setMetadata("RegInfo", regInfoNode);
1506 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1507 llvm::SmallVector<llvm::Value*, 50> pmap;
1508 for (int i = 0; i < promoSize; i++) {
1509 PromotionMap* p = &cUnit->promotionMap[i];
1510 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1511 ((p->fpReg & 0xff) << 16) |
1512 ((p->coreReg & 0xff) << 8) |
1513 ((p->fpLocation & 0xf) << 4) |
1514 (p->coreLocation & 0xf);
1515 pmap.push_back(cUnit->irb->getInt32(mapData));
1516 }
1517 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1518 inst->setMetadata("PromotionMap", mapNode);
1519 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1520}
1521
1522/* Handle the content in each basic block */
1523bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1524{
1525 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1526 cUnit->irb->SetInsertPoint(llvmBB);
1527 setDexOffset(cUnit, bb->startOffset);
1528
1529 if (bb->blockType == kEntryBlock) {
1530 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001531 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1532 cUnit->numDalvikRegisters, true,
1533 kAllocMisc);
1534 for (int i = 0; i < cUnit->numSSARegs; i++) {
1535 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1536 }
1537 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1538 if (canBeRef[i]) {
1539 cUnit->numShadowFrameEntries++;
1540 }
1541 }
1542 if (cUnit->numShadowFrameEntries > 0) {
1543 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1544 cUnit->numShadowFrameEntries, true,
1545 kAllocMisc);
1546 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1547 if (canBeRef[i]) {
1548 cUnit->shadowMap[j++] = i;
1549 }
1550 }
1551 greenland::IntrinsicHelper::IntrinsicId id =
1552 greenland::IntrinsicHelper::AllocaShadowFrame;
1553 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1554 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1555 cUnit->irb->CreateCall(func, entries);
1556 }
buzbee2cfc6392012-05-07 14:51:40 -07001557 } else if (bb->blockType == kExitBlock) {
1558 /*
1559 * Because of the differences between how MIR/LIR and llvm handle exit
1560 * blocks, we won't explicitly covert them. On the llvm-to-lir
1561 * path, it will need to be regenereated.
1562 */
1563 return false;
buzbee6969d502012-06-15 16:40:31 -07001564 } else if (bb->blockType == kExceptionHandling) {
1565 /*
1566 * Because we're deferring null checking, delete the associated empty
1567 * exception block.
1568 * TODO: add new block type for exception blocks that we generate
1569 * greenland code for.
1570 */
1571 llvmBB->eraseFromParent();
1572 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001573 }
1574
1575 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1576
1577 setDexOffset(cUnit, mir->offset);
1578
1579 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
1580 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
1581
1582 /* If we're compiling for the debugger, generate an update callout */
1583 if (cUnit->genDebugger) {
1584 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1585 //genDebuggerUpdate(cUnit, mir->offset);
1586 }
1587
1588 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
1589 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1590 continue;
1591 }
1592
1593 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1594 NULL /* labelList */);
1595 if (notHandled) {
1596 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
1597 mir->offset, dalvikOpcode,
1598 Instruction::Name(dalvikOpcode),
1599 dalvikFormat);
1600 }
1601 }
1602
buzbee6969d502012-06-15 16:40:31 -07001603 if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001604 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1605 }
1606
1607 return false;
1608}
1609
1610llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1611
1612 // Get return type
1613 llvm::Type* ret_type = cUnit->irb->GetJType(cUnit->shorty[0],
1614 greenland::kAccurate);
1615
1616 // Get argument type
1617 std::vector<llvm::Type*> args_type;
1618
1619 // method object
1620 args_type.push_back(cUnit->irb->GetJMethodTy());
1621
1622 // Do we have a "this"?
1623 if ((cUnit->access_flags & kAccStatic) == 0) {
1624 args_type.push_back(cUnit->irb->GetJObjectTy());
1625 }
1626
1627 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
1628 args_type.push_back(cUnit->irb->GetJType(cUnit->shorty[i],
1629 greenland::kAccurate));
1630 }
1631
1632 return llvm::FunctionType::get(ret_type, args_type, false);
1633}
1634
1635bool createFunction(CompilationUnit* cUnit) {
1636 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1637 /* with_signature */ false));
1638 llvm::FunctionType* func_type = getFunctionType(cUnit);
1639
1640 if (func_type == NULL) {
1641 return false;
1642 }
1643
1644 cUnit->func = llvm::Function::Create(func_type,
1645 llvm::Function::ExternalLinkage,
1646 func_name, cUnit->module);
1647
1648 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1649 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1650
1651 arg_iter->setName("method");
1652 ++arg_iter;
1653
1654 int startSReg = cUnit->numRegs;
1655
1656 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1657 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1658 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1659 }
1660
1661 return true;
1662}
1663
1664bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1665{
1666 // Skip the exit block
1667 if (bb->blockType == kExitBlock) {
1668 cUnit->idToBlockMap.Put(bb->id, NULL);
1669 } else {
1670 int offset = bb->startOffset;
1671 bool entryBlock = (bb->blockType == kEntryBlock);
1672 llvm::BasicBlock* llvmBB =
1673 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
Elliott Hughes74847412012-06-20 18:10:21 -07001674 StringPrintf(kLabelFormat, offset, bb->id),
buzbee2cfc6392012-05-07 14:51:40 -07001675 cUnit->func);
1676 if (entryBlock) {
1677 cUnit->entryBB = llvmBB;
1678 cUnit->placeholderBB =
1679 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1680 cUnit->func);
1681 }
1682 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1683 }
1684 return false;
1685}
1686
1687
1688/*
1689 * Convert MIR to LLVM_IR
1690 * o For each ssa name, create LLVM named value. Type these
1691 * appropriately, and ignore high half of wide and double operands.
1692 * o For each MIR basic block, create an LLVM basic block.
1693 * o Iterate through the MIR a basic block at a time, setting arguments
1694 * to recovered ssa name.
1695 */
1696void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
1697{
1698 initIR(cUnit);
1699 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
1700
1701 // Create the function
1702 createFunction(cUnit);
1703
1704 // Create an LLVM basic block for each MIR block in dfs preorder
1705 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
1706 kPreOrderDFSTraversal, false /* isIterative */);
1707 /*
1708 * Create an llvm named value for each MIR SSA name. Note: we'll use
1709 * placeholders for all non-argument values (because we haven't seen
1710 * the definition yet).
1711 */
1712 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
1713 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1714 arg_iter++; /* Skip path method */
1715 for (int i = 0; i < cUnit->numSSARegs; i++) {
1716 llvm::Value* val;
1717 llvm::Type* ty = llvmTypeFromLocRec(cUnit, cUnit->regLocation[i]);
1718 if (i < cUnit->numRegs) {
1719 // Skip non-argument _0 names - should never be a use
1720 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)0);
1721 } else if (i >= (cUnit->numRegs + cUnit->numIns)) {
1722 // Handle SSA defs, skipping Method* and compiler temps
1723 if (SRegToVReg(cUnit, i) < 0) {
1724 val = NULL;
1725 } else {
1726 val = cUnit->irb->CreateLoad(cUnit->irb->CreateAlloca(ty, 0));
1727 val->setName(llvmSSAName(cUnit, i));
1728 }
1729 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
1730 if (cUnit->regLocation[i].wide) {
1731 // Skip high half of wide values
1732 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1733 i++;
1734 }
1735 } else {
1736 // Recover previously-created argument values
1737 llvm::Value* argVal = arg_iter++;
1738 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
1739 }
1740 }
1741 cUnit->irb->CreateBr(cUnit->placeholderBB);
1742
1743 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
1744 kPreOrderDFSTraversal, false /* Iterative */);
1745
1746 cUnit->placeholderBB->eraseFromParent();
1747
1748 llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction);
1749
buzbeead8f15e2012-06-18 14:49:45 -07001750 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
1751 // Write bitcode to file
1752 std::string errmsg;
1753 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
1754 oatReplaceSpecialChars(fname);
1755 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07001756 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07001757
buzbeead8f15e2012-06-18 14:49:45 -07001758 llvm::OwningPtr<llvm::tool_output_file> out_file(
1759 new llvm::tool_output_file(fname.c_str(), errmsg,
1760 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07001761
buzbeead8f15e2012-06-18 14:49:45 -07001762 if (!errmsg.empty()) {
1763 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
1764 }
1765
1766 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
1767 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07001768 }
buzbee2cfc6392012-05-07 14:51:40 -07001769}
1770
1771RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
1772 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07001773 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001774 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
1775 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07001776 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07001777 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07001778 // FIXME: need to be more robust, handle FP and be in a position to
1779 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07001780 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
1781 memset(&res, 0, sizeof(res));
1782 res.location = kLocPhysReg;
1783 res.lowReg = oatAllocTemp(cUnit);
1784 res.home = true;
1785 res.sRegLow = INVALID_SREG;
1786 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07001787 llvm::Type* ty = val->getType();
1788 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
1789 (ty == cUnit->irb->getDoubleTy()));
1790 if (res.wide) {
1791 res.highReg = oatAllocTemp(cUnit);
1792 }
buzbee4f1181f2012-06-22 13:52:12 -07001793 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07001794 } else {
1795 DCHECK_EQ(valName[0], 'v');
1796 int baseSReg = INVALID_SREG;
1797 sscanf(valName.c_str(), "v%d_", &baseSReg);
1798 res = cUnit->regLocation[baseSReg];
1799 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07001800 }
1801 } else {
1802 res = it->second;
1803 }
1804 return res;
1805}
1806
1807Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
1808{
1809 Instruction::Code res = Instruction::NOP;
1810 if (isWide) {
1811 switch(op) {
1812 case kOpAdd: res = Instruction::ADD_LONG; break;
1813 case kOpSub: res = Instruction::SUB_LONG; break;
1814 case kOpMul: res = Instruction::MUL_LONG; break;
1815 case kOpDiv: res = Instruction::DIV_LONG; break;
1816 case kOpRem: res = Instruction::REM_LONG; break;
1817 case kOpAnd: res = Instruction::AND_LONG; break;
1818 case kOpOr: res = Instruction::OR_LONG; break;
1819 case kOpXor: res = Instruction::XOR_LONG; break;
1820 case kOpLsl: res = Instruction::SHL_LONG; break;
1821 case kOpLsr: res = Instruction::USHR_LONG; break;
1822 case kOpAsr: res = Instruction::SHR_LONG; break;
1823 default: LOG(FATAL) << "Unexpected OpKind " << op;
1824 }
1825 } else if (isConst){
1826 switch(op) {
1827 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
1828 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
1829 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
1830 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
1831 case kOpRem: res = Instruction::REM_INT_LIT16; break;
1832 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
1833 case kOpOr: res = Instruction::OR_INT_LIT16; break;
1834 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
1835 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
1836 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
1837 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
1838 default: LOG(FATAL) << "Unexpected OpKind " << op;
1839 }
1840 } else {
1841 switch(op) {
1842 case kOpAdd: res = Instruction::ADD_INT; break;
1843 case kOpSub: res = Instruction::SUB_INT; break;
1844 case kOpMul: res = Instruction::MUL_INT; break;
1845 case kOpDiv: res = Instruction::DIV_INT; break;
1846 case kOpRem: res = Instruction::REM_INT; break;
1847 case kOpAnd: res = Instruction::AND_INT; break;
1848 case kOpOr: res = Instruction::OR_INT; break;
1849 case kOpXor: res = Instruction::XOR_INT; break;
1850 case kOpLsl: res = Instruction::SHL_INT; break;
1851 case kOpLsr: res = Instruction::USHR_INT; break;
1852 case kOpAsr: res = Instruction::SHR_INT; break;
1853 default: LOG(FATAL) << "Unexpected OpKind " << op;
1854 }
1855 }
1856 return res;
1857}
1858
buzbee4f1181f2012-06-22 13:52:12 -07001859Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
1860{
1861 Instruction::Code res = Instruction::NOP;
1862 if (isWide) {
1863 switch(op) {
1864 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
1865 case kOpSub: res = Instruction::SUB_DOUBLE; break;
1866 case kOpMul: res = Instruction::MUL_DOUBLE; break;
1867 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
1868 case kOpRem: res = Instruction::REM_DOUBLE; break;
1869 default: LOG(FATAL) << "Unexpected OpKind " << op;
1870 }
1871 } else {
1872 switch(op) {
1873 case kOpAdd: res = Instruction::ADD_FLOAT; break;
1874 case kOpSub: res = Instruction::SUB_FLOAT; break;
1875 case kOpMul: res = Instruction::MUL_FLOAT; break;
1876 case kOpDiv: res = Instruction::DIV_FLOAT; break;
1877 case kOpRem: res = Instruction::REM_FLOAT; break;
1878 default: LOG(FATAL) << "Unexpected OpKind " << op;
1879 }
1880 }
1881 return res;
1882}
1883
1884void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
1885{
1886 RegLocation rlDest = getLoc(cUnit, inst);
1887 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1888 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
1889 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
1890 if (rlDest.wide) {
1891 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1892 } else {
1893 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1894 }
1895}
1896
buzbee101305f2012-06-28 18:00:56 -07001897void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
1898 Instruction::Code opcode)
1899{
1900 RegLocation rlDest = getLoc(cUnit, inst);
1901 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
1902 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
1903}
1904
1905void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
1906{
1907 // TODO: evaluate src/tgt types and add general support for more than int to long
1908 RegLocation rlDest = getLoc(cUnit, inst);
1909 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
1910 DCHECK(rlDest.wide);
1911 DCHECK(!rlSrc.wide);
1912 DCHECK(!rlDest.fp);
1913 DCHECK(!rlSrc.fp);
1914 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
1915 if (rlSrc.location == kLocPhysReg) {
1916 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
1917 } else {
1918 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
1919 }
1920 if (isSigned) {
1921 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
1922 } else {
1923 loadConstant(cUnit, rlResult.highReg, 0);
1924 }
1925 storeValueWide(cUnit, rlDest, rlResult);
1926}
1927
buzbee2cfc6392012-05-07 14:51:40 -07001928void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
1929{
1930 RegLocation rlDest = getLoc(cUnit, inst);
1931 llvm::Value* lhs = inst->getOperand(0);
buzbee4f1181f2012-06-22 13:52:12 -07001932 // Special-case RSUB
1933 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
1934 if ((op == kOpSub) && (lhsImm != NULL)) {
1935 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
1936 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
1937 lhsImm->getSExtValue());
1938 return;
1939 }
1940 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001941 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1942 llvm::Value* rhs = inst->getOperand(1);
1943 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
1944 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
1945 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, src2->getSExtValue());
1946 } else {
1947 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
1948 RegLocation rlSrc2 = getLoc(cUnit, rhs);
1949 if (rlDest.wide) {
1950 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1951 } else {
1952 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1953 }
1954 }
1955}
1956
buzbee101305f2012-06-28 18:00:56 -07001957void cvtShiftOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
1958{
1959 if (inst->getType() == cUnit->irb->getInt64Ty()) {
1960 /*
1961 * llvm wants the shift amount to be 64 bits, whereas we've constained
1962 * it to be in 6 bits. It should always be held as an unnamed temp
1963 * at this point that was the result of a previous UExt. We'll backtrack
1964 * to find the pre-extension value and use that.
1965 * TODO: probably better to handle this in cvtIntExt() or just intrinsify
1966 */
1967 RegLocation rlDest = getLoc(cUnit, inst);
1968 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
1969 RegLocation rlShift = getLoc(cUnit, inst->getOperand(1));
1970 DCHECK(rlShift.wide);
1971 DCHECK_EQ(rlShift.sRegLow, INVALID_SREG);
1972 // Now, free the temp registers - we won't need them.
1973 // TODO: kill the dead extend ops
1974 oatFreeTemp(cUnit, rlShift.lowReg);
1975 oatFreeTemp(cUnit, rlShift.highReg);
1976 // Get the pre-extend operand
1977 llvm::Instruction* extInst =
1978 llvm::dyn_cast<llvm::Instruction>(inst->getOperand(1));
1979 DCHECK(extInst != NULL);
1980 rlShift = getLoc(cUnit, extInst->getOperand(0));
1981 DCHECK(!rlShift.wide);
1982 Instruction::Code opcode;
1983 if (op == kOpLsl)
1984 opcode = Instruction::SHL_LONG;
1985 else if (op == kOpAsr)
1986 opcode = Instruction::SHR_LONG;
1987 else {
1988 DCHECK_EQ(op, kOpLsr);
1989 opcode = Instruction::USHR_LONG;
1990 }
1991 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
1992 } else {
1993 cvtBinOp(cUnit, op, inst);
1994 }
1995}
1996
buzbee2cfc6392012-05-07 14:51:40 -07001997void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
1998{
1999 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2000 DCHECK(brInst != NULL);
2001 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2002 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2003 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2004}
2005
2006void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2007{
2008 // Nop - these have already been processed
2009}
2010
2011void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2012{
2013 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2014 llvm::Value* retVal = retInst->getReturnValue();
2015 if (retVal != NULL) {
2016 RegLocation rlSrc = getLoc(cUnit, retVal);
2017 if (rlSrc.wide) {
2018 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2019 } else {
2020 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2021 }
2022 }
2023 genExitSequence(cUnit);
2024}
2025
2026ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2027{
2028 ConditionCode res = kCondAl;
2029 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002030 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002031 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2032 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2033 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002034 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002035 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002036 default: LOG(FATAL) << "Unexpected llvm condition";
2037 }
2038 return res;
2039}
2040
2041void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2042{
2043 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2044 UNIMPLEMENTED(FATAL);
2045}
2046
2047void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2048 llvm::BranchInst* brInst)
2049{
2050 // Get targets
2051 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2052 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2053 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2054 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2055 // Get comparison operands
2056 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2057 ConditionCode cond = getCond(iCmpInst->getPredicate());
2058 llvm::Value* lhs = iCmpInst->getOperand(0);
2059 // Not expecting a constant as 1st operand
2060 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2061 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2062 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2063 llvm::Value* rhs = inst->getOperand(1);
2064#if defined(TARGET_MIPS)
2065 // Compare and branch in one shot
2066 (void)taken;
2067 (void)cond;
2068 (void)rhs;
2069 UNIMPLEMENTED(FATAL);
2070#else
2071 //Compare, then branch
2072 // TODO: handle fused CMP_LONG/IF_xxZ case
2073 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2074 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
2075 } else {
2076 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2077 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2078 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2079 }
2080 opCondBranch(cUnit, cond, taken);
2081#endif
2082 // Fallthrough
2083 opUnconditionalBranch(cUnit, fallThrough);
2084}
2085
2086void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2087 llvm::Function* callee)
2088{
2089 UNIMPLEMENTED(FATAL);
2090}
2091
buzbee2cfc6392012-05-07 14:51:40 -07002092void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2093{
buzbee4f1181f2012-06-22 13:52:12 -07002094 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002095 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2096 RegLocation rlDest = getLoc(cUnit, callInst);
2097 if (rlSrc.wide) {
2098 storeValueWide(cUnit, rlDest, rlSrc);
2099 } else {
2100 storeValue(cUnit, rlDest, rlSrc);
2101 }
2102}
2103
2104// Note: Immediate arg is a ConstantInt regardless of result type
2105void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2106{
buzbee4f1181f2012-06-22 13:52:12 -07002107 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002108 llvm::ConstantInt* src =
2109 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2110 uint64_t immval = src->getZExtValue();
2111 RegLocation rlDest = getLoc(cUnit, callInst);
2112 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2113 if (rlDest.wide) {
2114 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2115 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2116 storeValueWide(cUnit, rlDest, rlResult);
2117 } else {
2118 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2119 storeValue(cUnit, rlDest, rlResult);
2120 }
2121}
2122
buzbee101305f2012-06-28 18:00:56 -07002123void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2124 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002125{
buzbee4f1181f2012-06-22 13:52:12 -07002126 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002127 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002128 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002129 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002130 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002131 if (isString) {
2132 genConstString(cUnit, index, rlDest);
2133 } else {
2134 genConstClass(cUnit, index, rlDest);
2135 }
2136}
2137
2138void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2139{
2140 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2141 llvm::ConstantInt* offsetVal =
2142 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2143 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2144 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002145}
2146
buzbee4f1181f2012-06-22 13:52:12 -07002147void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2148{
buzbee32412962012-06-26 16:27:56 -07002149 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002150 llvm::ConstantInt* typeIdxVal =
2151 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2152 uint32_t typeIdx = typeIdxVal->getZExtValue();
2153 RegLocation rlDest = getLoc(cUnit, callInst);
2154 genNewInstance(cUnit, typeIdx, rlDest);
2155}
2156
buzbee8fa0fda2012-06-27 15:44:52 -07002157void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2158{
2159 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2160 llvm::ConstantInt* typeIdxVal =
2161 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2162 uint32_t typeIdx = typeIdxVal->getZExtValue();
2163 llvm::Value* len = callInst->getArgOperand(1);
2164 RegLocation rlLen = getLoc(cUnit, len);
2165 RegLocation rlDest = getLoc(cUnit, callInst);
2166 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2167}
2168
2169void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2170{
2171 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2172 llvm::ConstantInt* typeIdxVal =
2173 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2174 uint32_t typeIdx = typeIdxVal->getZExtValue();
2175 llvm::Value* src = callInst->getArgOperand(1);
2176 RegLocation rlSrc = getLoc(cUnit, src);
2177 RegLocation rlDest = getLoc(cUnit, callInst);
2178 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2179}
2180
buzbee32412962012-06-26 16:27:56 -07002181void cvtThrowVerificationError(CompilationUnit* cUnit, llvm::CallInst* callInst)
2182{
2183 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2184 llvm::ConstantInt* info1 =
2185 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2186 llvm::ConstantInt* info2 =
2187 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2188 genThrowVerificationError(cUnit, info1->getZExtValue(), info2->getZExtValue());
2189}
2190
2191void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2192{
2193 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2194 llvm::Value* src = callInst->getArgOperand(0);
2195 RegLocation rlSrc = getLoc(cUnit, src);
2196 genThrow(cUnit, rlSrc);
2197}
2198
buzbee8fa0fda2012-06-27 15:44:52 -07002199void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2200 llvm::CallInst* callInst)
2201{
2202 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2203 llvm::ConstantInt* optFlags =
2204 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2205 llvm::Value* src = callInst->getArgOperand(1);
2206 RegLocation rlSrc = getLoc(cUnit, src);
2207 if (isEnter) {
2208 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2209 } else {
2210 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2211 }
2212}
2213
2214void cvtMonitorArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
2215{
2216 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2217 llvm::ConstantInt* optFlags =
2218 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2219 llvm::Value* src = callInst->getArgOperand(1);
2220 RegLocation rlSrc = getLoc(cUnit, src);
2221 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2222 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2223 RegLocation rlDest = getLoc(cUnit, callInst);
2224 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2225 int lenOffset = Array::LengthOffset().Int32Value();
2226 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2227 storeValue(cUnit, rlDest, rlResult);
2228}
2229
buzbee32412962012-06-26 16:27:56 -07002230void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2231{
2232 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
2233 int exOffset = Thread::ExceptionOffset().Int32Value();
2234 RegLocation rlDest = getLoc(cUnit, callInst);
2235 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2236#if defined(TARGET_X86)
2237 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
2238 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
2239#else
2240 int resetReg = oatAllocTemp(cUnit);
2241 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
2242 loadConstant(cUnit, resetReg, 0);
2243 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
2244 oatFreeTemp(cUnit, resetReg);
2245#endif
2246 storeValue(cUnit, rlDest, rlResult);
2247}
2248
buzbee4f1181f2012-06-22 13:52:12 -07002249void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2250 bool isObject)
2251{
buzbee32412962012-06-26 16:27:56 -07002252 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002253 llvm::ConstantInt* typeIdxVal =
2254 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2255 uint32_t typeIdx = typeIdxVal->getZExtValue();
2256 RegLocation rlDest = getLoc(cUnit, callInst);
2257 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2258}
2259
buzbee8fa0fda2012-06-27 15:44:52 -07002260void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2261 bool isObject)
2262{
2263 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2264 llvm::ConstantInt* typeIdxVal =
2265 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2266 uint32_t typeIdx = typeIdxVal->getZExtValue();
2267 llvm::Value* src = callInst->getArgOperand(1);
2268 RegLocation rlSrc = getLoc(cUnit, src);
2269 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2270}
2271
2272void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2273 int scale)
2274{
2275 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2276 llvm::ConstantInt* optFlags =
2277 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2278 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2279 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2280 RegLocation rlDest = getLoc(cUnit, callInst);
2281 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2282 rlDest, scale);
2283}
2284
2285void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2286 int scale)
2287{
2288 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2289 llvm::ConstantInt* optFlags =
2290 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2291 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2292 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2293 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
2294 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2295 rlSrc, scale);
2296}
2297
buzbee101305f2012-06-28 18:00:56 -07002298void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2299 bool isWide, bool isObj)
2300{
2301 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2302 llvm::ConstantInt* optFlags =
2303 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2304 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2305 llvm::ConstantInt* fieldIdx =
2306 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2307 RegLocation rlDest = getLoc(cUnit, callInst);
2308 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2309 size, rlDest, rlObj, isWide, isObj);
2310}
2311
2312void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2313 bool isWide, bool isObj)
2314{
2315 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2316 llvm::ConstantInt* optFlags =
2317 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2318 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2319 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2320 llvm::ConstantInt* fieldIdx =
2321 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2322 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2323 size, rlSrc, rlObj, isWide, isObj);
2324}
2325
2326void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2327{
2328 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2329 llvm::ConstantInt* typeIdx =
2330 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2331 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2332 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2333}
2334
buzbee6969d502012-06-15 16:40:31 -07002335void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee101305f2012-06-28 18:00:56 -07002336 bool isVoid, bool isNewArray)
buzbee6969d502012-06-15 16:40:31 -07002337{
2338 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2339 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002340 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002341 info->result.location = kLocInvalid;
2342 } else {
2343 info->result = getLoc(cUnit, callInst);
2344 }
2345 llvm::ConstantInt* invokeTypeVal =
2346 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2347 llvm::ConstantInt* methodIndexVal =
2348 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2349 llvm::ConstantInt* optFlagsVal =
2350 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2351 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2352 info->index = methodIndexVal->getZExtValue();
2353 info->optFlags = optFlagsVal->getZExtValue();
2354 info->offset = cUnit->currentDalvikOffset;
2355
2356 // FIXME - rework such that we no longer need isRange
2357 info->isRange = false;
2358
2359 // Count the argument words, and then build argument array.
2360 info->numArgWords = 0;
2361 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2362 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2363 info->numArgWords += tLoc.wide ? 2 : 1;
2364 }
2365 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2366 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2367 // Now, fill in the location records, synthesizing high loc of wide vals
2368 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002369 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002370 if (cUnit->printMe) {
2371 oatDumpRegLoc(info->args[next]);
2372 }
2373 if (info->args[next].wide) {
2374 next++;
2375 // TODO: Might make sense to mark this as an invalid loc
2376 info->args[next].origSReg = info->args[next-1].origSReg+1;
2377 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2378 }
2379 next++;
2380 }
buzbee101305f2012-06-28 18:00:56 -07002381 if (isNewArray) {
2382 genFilledNewArray(cUnit, info);
2383 } else {
2384 genInvoke(cUnit, info);
2385 }
buzbee6969d502012-06-15 16:40:31 -07002386}
2387
buzbeead8f15e2012-06-18 14:49:45 -07002388/* Look up the RegLocation associated with a Value. Must already be defined */
2389RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2390{
2391 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2392 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2393 return it->second;
2394}
2395
buzbee2cfc6392012-05-07 14:51:40 -07002396bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2397{
2398 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2399 // Define the starting label
2400 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2401 // Extract the starting offset from the block's name
2402 if (!isEntry) {
2403 const char* blockName = bb->getName().str().c_str();
2404 int dummy;
Elliott Hughes74847412012-06-20 18:10:21 -07002405 sscanf(blockName, kLabelFormat, &blockLabel->operands[0], &dummy);
buzbee2cfc6392012-05-07 14:51:40 -07002406 }
2407 // Set the label kind
2408 blockLabel->opcode = kPseudoNormalBlockLabel;
2409 // Insert the label
2410 oatAppendLIR(cUnit, blockLabel);
2411
2412 // Free temp registers and reset redundant store tracking */
2413 oatResetRegPool(cUnit);
2414 oatResetDefTracking(cUnit);
2415
2416 //TODO: restore oat incoming liveness optimization
2417 oatClobberAllRegs(cUnit);
2418
buzbee6969d502012-06-15 16:40:31 -07002419 LIR* headLIR = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07002420
2421 if (isEntry) {
2422 cUnit->currentDalvikOffset = 0;
buzbeead8f15e2012-06-18 14:49:45 -07002423 RegLocation* argLocs = (RegLocation*)
2424 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2425 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2426 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2427 for (unsigned i = 0; it != it_end; ++it) {
2428 llvm::Value* val = it;
2429 argLocs[i++] = valToLoc(cUnit, val);
2430 llvm::Type* ty = val->getType();
2431 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2432 argLocs[i++].sRegLow = INVALID_SREG;
2433 }
2434 }
2435 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
buzbee2cfc6392012-05-07 14:51:40 -07002436 }
2437
2438 // Visit all of the instructions in the block
2439 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2440 llvm::Instruction* inst = it;
2441 llvm::BasicBlock::iterator nextIt = ++it;
2442 // Extract the Dalvik offset from the instruction
2443 uint32_t opcode = inst->getOpcode();
2444 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2445 if (dexOffsetNode != NULL) {
2446 llvm::ConstantInt* dexOffsetValue =
2447 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2448 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2449 }
2450
buzbee6969d502012-06-15 16:40:31 -07002451 oatResetRegPool(cUnit);
2452 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2453 oatClobberAllRegs(cUnit);
2454 }
2455
2456 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2457 oatResetDefTracking(cUnit);
2458 }
2459
2460#ifndef NDEBUG
2461 /* Reset temp tracking sanity check */
2462 cUnit->liveSReg = INVALID_SREG;
2463#endif
2464
2465 LIR* boundaryLIR;
2466 const char* instStr = "boundary";
2467 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
2468 (intptr_t) instStr);
2469 cUnit->boundaryMap.Overwrite(cUnit->currentDalvikOffset, boundaryLIR);
2470
2471 /* Remember the first LIR for thisl block*/
2472 if (headLIR == NULL) {
2473 headLIR = boundaryLIR;
2474 headLIR->defMask = ENCODE_ALL;
2475 }
2476
buzbee2cfc6392012-05-07 14:51:40 -07002477 switch(opcode) {
2478
2479 case llvm::Instruction::ICmp: {
2480 llvm::Instruction* nextInst = nextIt;
2481 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2482 if (brInst != NULL /* and... */) {
2483 cvtICmpBr(cUnit, inst, brInst);
2484 ++it;
2485 } else {
2486 cvtICmp(cUnit, inst);
2487 }
2488 }
2489 break;
2490
2491 case llvm::Instruction::Call: {
2492 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2493 llvm::Function* callee = callInst->getCalledFunction();
2494 greenland::IntrinsicHelper::IntrinsicId id =
2495 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2496 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07002497 case greenland::IntrinsicHelper::AllocaShadowFrame:
2498 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07002499 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07002500 // Ignore shadow frame stuff for quick compiler
2501 break;
buzbee2cfc6392012-05-07 14:51:40 -07002502 case greenland::IntrinsicHelper::CopyInt:
2503 case greenland::IntrinsicHelper::CopyObj:
2504 case greenland::IntrinsicHelper::CopyFloat:
2505 case greenland::IntrinsicHelper::CopyLong:
2506 case greenland::IntrinsicHelper::CopyDouble:
2507 cvtCopy(cUnit, callInst);
2508 break;
2509 case greenland::IntrinsicHelper::ConstInt:
2510 case greenland::IntrinsicHelper::ConstObj:
2511 case greenland::IntrinsicHelper::ConstLong:
2512 case greenland::IntrinsicHelper::ConstFloat:
2513 case greenland::IntrinsicHelper::ConstDouble:
2514 cvtConst(cUnit, callInst);
2515 break;
buzbee4f1181f2012-06-22 13:52:12 -07002516 case greenland::IntrinsicHelper::DivInt:
2517 case greenland::IntrinsicHelper::DivLong:
2518 cvtBinOp(cUnit, kOpDiv, inst);
2519 break;
2520 case greenland::IntrinsicHelper::RemInt:
2521 case greenland::IntrinsicHelper::RemLong:
2522 cvtBinOp(cUnit, kOpRem, inst);
2523 break;
buzbee2cfc6392012-05-07 14:51:40 -07002524 case greenland::IntrinsicHelper::MethodInfo:
buzbeead8f15e2012-06-18 14:49:45 -07002525 // Already dealt with - just ignore it here.
buzbee2cfc6392012-05-07 14:51:40 -07002526 break;
2527 case greenland::IntrinsicHelper::CheckSuspend:
2528 genSuspendTest(cUnit, 0 /* optFlags already applied */);
2529 break;
buzbee4f1181f2012-06-22 13:52:12 -07002530 case greenland::IntrinsicHelper::HLInvokeObj:
buzbee8fa0fda2012-06-27 15:44:52 -07002531 case greenland::IntrinsicHelper::HLInvokeFloat:
2532 case greenland::IntrinsicHelper::HLInvokeDouble:
2533 case greenland::IntrinsicHelper::HLInvokeLong:
2534 case greenland::IntrinsicHelper::HLInvokeInt:
buzbee101305f2012-06-28 18:00:56 -07002535 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
buzbee4f1181f2012-06-22 13:52:12 -07002536 break;
buzbee6969d502012-06-15 16:40:31 -07002537 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbee101305f2012-06-28 18:00:56 -07002538 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
2539 break;
2540 case greenland::IntrinsicHelper::FilledNewArray:
2541 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
2542 break;
2543 case greenland::IntrinsicHelper::FillArrayData:
2544 cvtFillArrayData(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07002545 break;
2546 case greenland::IntrinsicHelper::ConstString:
buzbee101305f2012-06-28 18:00:56 -07002547 cvtConstObject(cUnit, callInst, true /* isString */);
2548 break;
2549 case greenland::IntrinsicHelper::ConstClass:
2550 cvtConstObject(cUnit, callInst, false /* isString */);
2551 break;
2552 case greenland::IntrinsicHelper::CheckCast:
2553 cvtCheckCast(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07002554 break;
buzbee4f1181f2012-06-22 13:52:12 -07002555 case greenland::IntrinsicHelper::NewInstance:
2556 cvtNewInstance(cUnit, callInst);
2557 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002558 case greenland::IntrinsicHelper::HLSgetObject:
buzbee4f1181f2012-06-22 13:52:12 -07002559 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
2560 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002561 case greenland::IntrinsicHelper::HLSget:
2562 case greenland::IntrinsicHelper::HLSgetFloat:
2563 case greenland::IntrinsicHelper::HLSgetBoolean:
2564 case greenland::IntrinsicHelper::HLSgetByte:
2565 case greenland::IntrinsicHelper::HLSgetChar:
2566 case greenland::IntrinsicHelper::HLSgetShort:
2567 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
2568 break;
2569 case greenland::IntrinsicHelper::HLSgetWide:
2570 case greenland::IntrinsicHelper::HLSgetDouble:
2571 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
2572 break;
buzbee32412962012-06-26 16:27:56 -07002573 case greenland::IntrinsicHelper::GetException:
2574 cvtMoveException(cUnit, callInst);
2575 break;
2576 case greenland::IntrinsicHelper::Throw:
2577 cvtThrow(cUnit, callInst);
2578 break;
2579 case greenland::IntrinsicHelper::ThrowVerificationError:
buzbee8fa0fda2012-06-27 15:44:52 -07002580 cvtThrowVerificationError(cUnit, callInst);
buzbee32412962012-06-26 16:27:56 -07002581 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002582 case greenland::IntrinsicHelper::MonitorEnter:
2583 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
2584 break;
2585 case greenland::IntrinsicHelper::MonitorExit:
2586 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
2587 break;
2588 case greenland::IntrinsicHelper::ArrayLength:
2589 cvtMonitorArrayLength(cUnit, callInst);
2590 break;
2591 case greenland::IntrinsicHelper::NewArray:
2592 cvtNewArray(cUnit, callInst);
2593 break;
2594 case greenland::IntrinsicHelper::InstanceOf:
2595 cvtInstanceOf(cUnit, callInst);
2596 break;
2597
2598 case greenland::IntrinsicHelper::HLArrayGet:
2599 case greenland::IntrinsicHelper::HLArrayGetObject:
2600 case greenland::IntrinsicHelper::HLArrayGetFloat:
2601 cvtAget(cUnit, callInst, kWord, 2);
2602 break;
2603 case greenland::IntrinsicHelper::HLArrayGetWide:
2604 case greenland::IntrinsicHelper::HLArrayGetDouble:
2605 cvtAget(cUnit, callInst, kLong, 3);
2606 break;
2607 case greenland::IntrinsicHelper::HLArrayGetBoolean:
2608 cvtAget(cUnit, callInst, kUnsignedByte, 0);
2609 break;
2610 case greenland::IntrinsicHelper::HLArrayGetByte:
2611 cvtAget(cUnit, callInst, kSignedByte, 0);
2612 break;
2613 case greenland::IntrinsicHelper::HLArrayGetChar:
2614 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
2615 break;
2616 case greenland::IntrinsicHelper::HLArrayGetShort:
2617 cvtAget(cUnit, callInst, kSignedHalf, 1);
2618 break;
2619
2620 case greenland::IntrinsicHelper::HLArrayPut:
2621 case greenland::IntrinsicHelper::HLArrayPutObject:
2622 case greenland::IntrinsicHelper::HLArrayPutFloat:
2623 cvtAput(cUnit, callInst, kWord, 2);
2624 break;
2625 case greenland::IntrinsicHelper::HLArrayPutWide:
2626 case greenland::IntrinsicHelper::HLArrayPutDouble:
2627 cvtAput(cUnit, callInst, kLong, 3);
2628 break;
2629 case greenland::IntrinsicHelper::HLArrayPutBoolean:
2630 cvtAput(cUnit, callInst, kUnsignedByte, 0);
2631 break;
2632 case greenland::IntrinsicHelper::HLArrayPutByte:
2633 cvtAput(cUnit, callInst, kSignedByte, 0);
2634 break;
2635 case greenland::IntrinsicHelper::HLArrayPutChar:
2636 cvtAput(cUnit, callInst, kUnsignedHalf, 1);
2637 break;
2638 case greenland::IntrinsicHelper::HLArrayPutShort:
2639 cvtAput(cUnit, callInst, kSignedHalf, 1);
2640 break;
2641
buzbee101305f2012-06-28 18:00:56 -07002642 case greenland::IntrinsicHelper::HLIGet:
2643 case greenland::IntrinsicHelper::HLIGetFloat:
2644 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
2645 break;
2646 case greenland::IntrinsicHelper::HLIGetObject:
2647 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
2648 break;
2649 case greenland::IntrinsicHelper::HLIGetWide:
2650 case greenland::IntrinsicHelper::HLIGetDouble:
2651 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
2652 break;
2653 case greenland::IntrinsicHelper::HLIGetBoolean:
2654 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
2655 false /* obj */);
2656 break;
2657 case greenland::IntrinsicHelper::HLIGetByte:
2658 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
2659 false /* obj */);
2660 break;
2661 case greenland::IntrinsicHelper::HLIGetChar:
2662 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
2663 false /* obj */);
2664 break;
2665 case greenland::IntrinsicHelper::HLIGetShort:
2666 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
2667 false /* obj */);
2668 break;
2669
2670 case greenland::IntrinsicHelper::HLIPut:
2671 case greenland::IntrinsicHelper::HLIPutFloat:
2672 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
2673 break;
2674 case greenland::IntrinsicHelper::HLIPutObject:
2675 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
2676 break;
2677 case greenland::IntrinsicHelper::HLIPutWide:
2678 case greenland::IntrinsicHelper::HLIPutDouble:
2679 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
2680 break;
2681 case greenland::IntrinsicHelper::HLIPutBoolean:
2682 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
2683 false /* obj */);
2684 break;
2685 case greenland::IntrinsicHelper::HLIPutByte:
2686 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
2687 false /* obj */);
2688 break;
2689 case greenland::IntrinsicHelper::HLIPutChar:
2690 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
2691 false /* obj */);
2692 break;
2693 case greenland::IntrinsicHelper::HLIPutShort:
2694 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
2695 false /* obj */);
2696 break;
2697
2698 case greenland::IntrinsicHelper::IntToChar:
2699 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
2700 break;
2701 case greenland::IntrinsicHelper::IntToShort:
2702 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
2703 break;
2704 case greenland::IntrinsicHelper::IntToByte:
2705 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
2706 break;
2707
buzbee2cfc6392012-05-07 14:51:40 -07002708 case greenland::IntrinsicHelper::UnknownId:
2709 cvtCall(cUnit, callInst, callee);
2710 break;
2711 default:
2712 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
2713 << cUnit->intrinsic_helper->GetName(id);
2714 }
2715 }
2716 break;
2717
2718 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
2719 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
2720 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
2721 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
2722 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
2723 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
2724 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
2725 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
2726 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
buzbee101305f2012-06-28 18:00:56 -07002727 case llvm::Instruction::Shl: cvtShiftOp(cUnit, kOpLsl, inst); break;
2728 case llvm::Instruction::LShr: cvtShiftOp(cUnit, kOpLsr, inst); break;
2729 case llvm::Instruction::AShr: cvtShiftOp(cUnit, kOpAsr, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07002730 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
2731 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
buzbee4f1181f2012-06-22 13:52:12 -07002732 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
2733 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
2734 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
2735 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
2736 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07002737
buzbee101305f2012-06-28 18:00:56 -07002738 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
2739 break;
2740 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
2741 break;
2742
buzbee32412962012-06-26 16:27:56 -07002743 case llvm::Instruction::Unreachable:
2744 break; // FIXME: can we really ignore these?
2745
buzbee2cfc6392012-05-07 14:51:40 -07002746 case llvm::Instruction::Invoke:
buzbee2cfc6392012-05-07 14:51:40 -07002747 case llvm::Instruction::Trunc:
buzbee2cfc6392012-05-07 14:51:40 -07002748 case llvm::Instruction::FPToUI:
2749 case llvm::Instruction::FPToSI:
2750 case llvm::Instruction::UIToFP:
2751 case llvm::Instruction::SIToFP:
2752 case llvm::Instruction::FPTrunc:
2753 case llvm::Instruction::FPExt:
2754 case llvm::Instruction::PtrToInt:
2755 case llvm::Instruction::IntToPtr:
2756 case llvm::Instruction::Switch:
2757 case llvm::Instruction::FCmp:
buzbee101305f2012-06-28 18:00:56 -07002758 UNIMPLEMENTED(FATAL) << "Unimplemented llvm opcode: " << opcode;
buzbee4f1181f2012-06-22 13:52:12 -07002759 break;
buzbee2cfc6392012-05-07 14:51:40 -07002760
2761 case llvm::Instruction::URem:
2762 case llvm::Instruction::UDiv:
2763 case llvm::Instruction::Resume:
buzbee2cfc6392012-05-07 14:51:40 -07002764 case llvm::Instruction::Alloca:
2765 case llvm::Instruction::GetElementPtr:
2766 case llvm::Instruction::Fence:
2767 case llvm::Instruction::AtomicCmpXchg:
2768 case llvm::Instruction::AtomicRMW:
2769 case llvm::Instruction::BitCast:
2770 case llvm::Instruction::VAArg:
2771 case llvm::Instruction::Select:
2772 case llvm::Instruction::UserOp1:
2773 case llvm::Instruction::UserOp2:
2774 case llvm::Instruction::ExtractElement:
2775 case llvm::Instruction::InsertElement:
2776 case llvm::Instruction::ShuffleVector:
2777 case llvm::Instruction::ExtractValue:
2778 case llvm::Instruction::InsertValue:
2779 case llvm::Instruction::LandingPad:
2780 case llvm::Instruction::IndirectBr:
2781 case llvm::Instruction::Load:
2782 case llvm::Instruction::Store:
2783 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
2784
2785 default:
2786 LOG(FATAL) << "Unknown llvm opcode: " << opcode; break;
2787 }
2788 }
buzbee6969d502012-06-15 16:40:31 -07002789
2790 if (headLIR != NULL) {
2791 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
2792 }
buzbee2cfc6392012-05-07 14:51:40 -07002793 return false;
2794}
2795
2796/*
2797 * Convert LLVM_IR to MIR:
2798 * o Iterate through the LLVM_IR and construct a graph using
2799 * standard MIR building blocks.
2800 * o Perform a basic-block optimization pass to remove unnecessary
2801 * store/load sequences.
2802 * o Convert the LLVM Value operands into RegLocations where applicable.
2803 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
2804 * o Perform register promotion
2805 * o Iterate through the graph a basic block at a time, generating
2806 * LIR.
2807 * o Assemble LIR as usual.
2808 * o Profit.
2809 */
2810void oatMethodBitcode2LIR(CompilationUnit* cUnit)
2811{
buzbeead8f15e2012-06-18 14:49:45 -07002812 llvm::Function* func = cUnit->func;
2813 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07002814 // Allocate a list for LIR basic block labels
2815 cUnit->blockLabelList =
2816 (void*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
2817 LIR* labelList = (LIR*)cUnit->blockLabelList;
2818 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07002819 for (llvm::Function::iterator i = func->begin(),
2820 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07002821 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
2822 &labelList[nextLabel++]);
2823 }
buzbeead8f15e2012-06-18 14:49:45 -07002824
2825 /*
2826 * Keep honest - clear regLocations, Value => RegLocation,
2827 * promotion map and VmapTables.
2828 */
2829 cUnit->locMap.clear(); // Start fresh
2830 cUnit->regLocation = NULL;
2831 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
2832 i++) {
2833 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
2834 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
2835 }
2836 cUnit->coreSpillMask = 0;
2837 cUnit->numCoreSpills = 0;
2838 cUnit->fpSpillMask = 0;
2839 cUnit->numFPSpills = 0;
2840 cUnit->coreVmapTable.clear();
2841 cUnit->fpVmapTable.clear();
2842 oatAdjustSpillMask(cUnit);
2843 cUnit->frameSize = oatComputeFrameSize(cUnit);
2844
2845 /*
2846 * At this point, we've lost all knowledge of register promotion.
2847 * Rebuild that info from the MethodInfo intrinsic (if it
2848 * exists - not required for correctness).
2849 */
2850 // TODO: find and recover MethodInfo.
2851
2852 // Create RegLocations for arguments
2853 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2854 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2855 for (; it != it_end; ++it) {
2856 llvm::Value* val = it;
2857 createLocFromValue(cUnit, val);
2858 }
2859 // Create RegLocations for all non-argument defintions
2860 for (llvm::inst_iterator i = llvm::inst_begin(func),
2861 e = llvm::inst_end(func); i != e; ++i) {
2862 llvm::Value* val = &*i;
2863 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
2864 createLocFromValue(cUnit, val);
2865 }
2866 }
2867
buzbee2cfc6392012-05-07 14:51:40 -07002868 // Walk the blocks, generating code.
2869 for (llvm::Function::iterator i = cUnit->func->begin(),
2870 e = cUnit->func->end(); i != e; ++i) {
2871 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
2872 }
2873
2874 handleSuspendLaunchpads(cUnit);
2875
2876 handleThrowLaunchpads(cUnit);
2877
2878 handleIntrinsicLaunchpads(cUnit);
2879
2880 freeIR(cUnit);
2881}
2882
2883
2884} // namespace art
2885
2886#endif // ART_USE_QUICK_COMPILER