blob: 72e3e68b3ed6a868daa2acdb44835306d67673ed [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
buzbee2cfc6392012-05-07 14:51:40 -070017#include "object_utils.h"
18
19#include <llvm/Support/ToolOutputFile.h>
20#include <llvm/Bitcode/ReaderWriter.h>
21#include <llvm/Analysis/Verifier.h>
22#include <llvm/Metadata.h>
23#include <llvm/ADT/DepthFirstIterator.h>
24#include <llvm/Instruction.h>
25#include <llvm/Type.h>
26#include <llvm/Instructions.h>
27#include <llvm/Support/Casting.h>
buzbeead8f15e2012-06-18 14:49:45 -070028#include <llvm/Support/InstIterator.h>
buzbee2cfc6392012-05-07 14:51:40 -070029
buzbee1bc37c62012-11-20 13:35:41 -080030#include "../compiler_internals.h"
buzbeeeaf09bc2012-11-15 14:51:41 -080031#include "method_codegen_driver.h"
32#include "local_optimizations.h"
buzbee1bc37c62012-11-20 13:35:41 -080033#include "codegen_util.h"
34#include "ralloc_util.h"
buzbeeeaf09bc2012-11-15 14:51:41 -080035
buzbee8320f382012-09-11 16:29:42 -070036static const char* kLabelFormat = "%c0x%x_%d";
buzbee951c0a12012-10-03 16:31:39 -070037static const char kInvalidBlock = 0xff;
buzbee8320f382012-09-11 16:29:42 -070038static const char kNormalBlock = 'L';
39static const char kCatchBlock = 'C';
buzbee2cfc6392012-05-07 14:51:40 -070040
41namespace art {
buzbee1bc37c62012-11-20 13:35:41 -080042// TODO: unify badLoc
43const RegLocation badLoc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0,
44 INVALID_REG, INVALID_REG, INVALID_SREG,
45 INVALID_SREG};
buzbeeb03f4872012-06-11 15:22:11 -070046RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070047
48llvm::BasicBlock* getLLVMBlock(CompilationUnit* cUnit, int id)
49{
50 return cUnit->idToBlockMap.Get(id);
51}
52
53llvm::Value* getLLVMValue(CompilationUnit* cUnit, int sReg)
54{
buzbeecbd6d442012-11-17 14:11:25 -080055 return reinterpret_cast<llvm::Value*>(oatGrowableListGetElement(&cUnit->llvmValues, sReg));
buzbee2cfc6392012-05-07 14:51:40 -070056}
57
58// Replace the placeholder value with the real definition
59void defineValue(CompilationUnit* cUnit, llvm::Value* val, int sReg)
60{
61 llvm::Value* placeholder = getLLVMValue(cUnit, sReg);
buzbee9a2487f2012-07-26 14:01:13 -070062 if (placeholder == NULL) {
63 // This can happen on instruction rewrite on verification failure
Bill Buzbeec9f40dd2012-08-15 11:35:25 -070064 LOG(WARNING) << "Null placeholder";
buzbee9a2487f2012-07-26 14:01:13 -070065 return;
66 }
buzbee2cfc6392012-05-07 14:51:40 -070067 placeholder->replaceAllUsesWith(val);
68 val->takeName(placeholder);
buzbeecbd6d442012-11-17 14:11:25 -080069 cUnit->llvmValues.elemList[sReg] = reinterpret_cast<uintptr_t>(val);
buzbee4be777b2012-07-12 14:38:18 -070070 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
71 DCHECK(inst != NULL);
72 inst->eraseFromParent();
TDYa1278e950c12012-11-02 09:58:19 -070073
74 // Set vreg for debugging
75 if (!cUnit->compiler->IsDebuggingSupported()) {
76 greenland::IntrinsicHelper::IntrinsicId id =
77 greenland::IntrinsicHelper::SetVReg;
78 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
79 int vReg = SRegToVReg(cUnit, sReg);
80 llvm::Value* tableSlot = cUnit->irb->getInt32(vReg);
81 llvm::Value* args[] = { tableSlot, val };
82 cUnit->irb->CreateCall(func, args);
83 }
buzbee2cfc6392012-05-07 14:51:40 -070084}
85
86llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
87{
88 llvm::Type* res = NULL;
89 if (loc.wide) {
90 if (loc.fp)
buzbee4f1181f2012-06-22 13:52:12 -070091 res = cUnit->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070092 else
buzbee4f1181f2012-06-22 13:52:12 -070093 res = cUnit->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070094 } else {
95 if (loc.fp) {
buzbee4f1181f2012-06-22 13:52:12 -070096 res = cUnit->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070097 } else {
98 if (loc.ref)
99 res = cUnit->irb->GetJObjectTy();
100 else
buzbee4f1181f2012-06-22 13:52:12 -0700101 res = cUnit->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -0700102 }
103 }
104 return res;
105}
106
buzbeead8f15e2012-06-18 14:49:45 -0700107/* Create an in-memory RegLocation from an llvm Value. */
108void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
109{
110 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
111 std::string s(val->getName().str());
112 const char* valName = s.c_str();
buzbeead8f15e2012-06-18 14:49:45 -0700113 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
114 DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
115 int baseSReg = INVALID_SREG;
116 int subscript = -1;
117 sscanf(valName, "v%d_%d", &baseSReg, &subscript);
118 if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
119 baseSReg = SSA_METHOD_BASEREG;
120 subscript = 0;
121 }
buzbeead8f15e2012-06-18 14:49:45 -0700122 DCHECK_NE(baseSReg, INVALID_SREG);
123 DCHECK_NE(subscript, -1);
124 // TODO: redo during C++'ification
125 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
126 INVALID_REG, INVALID_SREG, INVALID_SREG};
127 llvm::Type* ty = val->getType();
128 loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
129 (ty == cUnit->irb->getDoubleTy()));
130 loc.defined = true;
buzbeeca7a5e42012-08-20 11:12:18 -0700131 loc.home = false; // May change during promotion
buzbeead8f15e2012-06-18 14:49:45 -0700132 loc.sRegLow = baseSReg;
133 loc.origSReg = cUnit->locMap.size();
buzbeeca7a5e42012-08-20 11:12:18 -0700134 PromotionMap pMap = cUnit->promotionMap[baseSReg];
135 if (ty == cUnit->irb->getFloatTy()) {
136 loc.fp = true;
137 if (pMap.fpLocation == kLocPhysReg) {
138 loc.lowReg = pMap.fpReg;
139 loc.location = kLocPhysReg;
140 loc.home = true;
141 }
142 } else if (ty == cUnit->irb->getDoubleTy()) {
143 loc.fp = true;
144 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
145 if ((pMap.fpLocation == kLocPhysReg) &&
146 (pMapHigh.fpLocation == kLocPhysReg) &&
147 ((pMap.fpReg & 0x1) == 0) &&
148 (pMap.fpReg + 1 == pMapHigh.fpReg)) {
149 loc.lowReg = pMap.fpReg;
150 loc.highReg = pMapHigh.fpReg;
151 loc.location = kLocPhysReg;
152 loc.home = true;
153 }
154 } else if (ty == cUnit->irb->GetJObjectTy()) {
155 loc.ref = true;
156 if (pMap.coreLocation == kLocPhysReg) {
157 loc.lowReg = pMap.coreReg;
158 loc.location = kLocPhysReg;
159 loc.home = true;
160 }
161 } else if (ty == cUnit->irb->getInt64Ty()) {
162 loc.core = true;
163 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
164 if ((pMap.coreLocation == kLocPhysReg) &&
165 (pMapHigh.coreLocation == kLocPhysReg)) {
166 loc.lowReg = pMap.coreReg;
167 loc.highReg = pMapHigh.coreReg;
168 loc.location = kLocPhysReg;
169 loc.home = true;
170 }
171 } else {
172 loc.core = true;
173 if (pMap.coreLocation == kLocPhysReg) {
174 loc.lowReg = pMap.coreReg;
175 loc.location = kLocPhysReg;
176 loc.home = true;
177 }
178 }
179
180 if (cUnit->printMe && loc.home) {
181 if (loc.wide) {
buzbeecbd6d442012-11-17 14:11:25 -0800182 LOG(INFO) << "Promoted wide " << s << " to regs " << loc.lowReg << "/" << loc.highReg;
buzbeeca7a5e42012-08-20 11:12:18 -0700183 } else {
buzbeecbd6d442012-11-17 14:11:25 -0800184 LOG(INFO) << "Promoted " << s << " to reg " << loc.lowReg;
buzbeeca7a5e42012-08-20 11:12:18 -0700185 }
186 }
buzbeead8f15e2012-06-18 14:49:45 -0700187 cUnit->locMap.Put(val, loc);
188}
buzbee2cfc6392012-05-07 14:51:40 -0700189void initIR(CompilationUnit* cUnit)
190{
buzbee4df2bbd2012-10-11 14:46:06 -0700191 LLVMInfo* llvmInfo = cUnit->llvm_info;
192 if (llvmInfo == NULL) {
193 CompilerTls* tls = cUnit->compiler->GetTls();
194 CHECK(tls != NULL);
195 llvmInfo = static_cast<LLVMInfo*>(tls->GetLLVMInfo());
196 if (llvmInfo == NULL) {
197 llvmInfo = new LLVMInfo();
198 tls->SetLLVMInfo(llvmInfo);
199 }
200 }
201 cUnit->context = llvmInfo->GetLLVMContext();
202 cUnit->module = llvmInfo->GetLLVMModule();
203 cUnit->intrinsic_helper = llvmInfo->GetIntrinsicHelper();
204 cUnit->irb = llvmInfo->GetIRBuilder();
buzbee2cfc6392012-05-07 14:51:40 -0700205}
206
207const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
208 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
209}
210
buzbeef58c12c2012-07-03 15:06:29 -0700211llvm::BasicBlock* findCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
212{
213 BasicBlock* bb = oatFindBlock(cUnit, vaddr);
214 DCHECK(bb != NULL);
215 return getLLVMBlock(cUnit, bb->id);
216}
217
218void convertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
219 int32_t tableOffset, RegLocation rlSrc)
220{
221 const Instruction::PackedSwitchPayload* payload =
222 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
223 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
224
225 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
226
227 llvm::SwitchInst* sw =
228 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
229 payload->case_count);
230
231 for (uint16_t i = 0; i < payload->case_count; ++i) {
232 llvm::BasicBlock* llvmBB =
233 findCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
234 sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
235 }
236 llvm::MDNode* switchNode =
237 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
238 sw->setMetadata("SwitchTable", switchNode);
239 bb->taken = NULL;
240 bb->fallThrough = NULL;
241}
242
buzbeea1da8a52012-07-09 14:00:21 -0700243void convertSparseSwitch(CompilationUnit* cUnit, BasicBlock* bb,
244 int32_t tableOffset, RegLocation rlSrc)
245{
246 const Instruction::SparseSwitchPayload* payload =
247 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
248 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
249
250 const int32_t* keys = payload->GetKeys();
251 const int32_t* targets = payload->GetTargets();
252
253 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
254
255 llvm::SwitchInst* sw =
256 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
257 payload->case_count);
258
259 for (size_t i = 0; i < payload->case_count; ++i) {
260 llvm::BasicBlock* llvmBB =
261 findCaseTarget(cUnit, cUnit->currentDalvikOffset + targets[i]);
262 sw->addCase(cUnit->irb->getInt32(keys[i]), llvmBB);
263 }
264 llvm::MDNode* switchNode =
265 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
266 sw->setMetadata("SwitchTable", switchNode);
267 bb->taken = NULL;
268 bb->fallThrough = NULL;
269}
270
buzbee8fa0fda2012-06-27 15:44:52 -0700271void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
272 greenland::IntrinsicHelper::IntrinsicId id,
273 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700274{
buzbee8fa0fda2012-06-27 15:44:52 -0700275 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700276 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700277 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
278 defineValue(cUnit, res, rlDest.origSReg);
279}
280
281void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
282 greenland::IntrinsicHelper::IntrinsicId id,
283 RegLocation rlSrc)
284{
285 llvm::SmallVector<llvm::Value*, 2> args;
286 args.push_back(cUnit->irb->getInt32(fieldIndex));
287 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
288 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
289 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700290}
291
buzbee101305f2012-06-28 18:00:56 -0700292void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
293 RegLocation rlArray)
294{
295 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700296 id = greenland::IntrinsicHelper::HLFillArrayData;
buzbee101305f2012-06-28 18:00:56 -0700297 llvm::SmallVector<llvm::Value*, 2> args;
298 args.push_back(cUnit->irb->getInt32(offset));
299 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
300 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
301 cUnit->irb->CreateCall(intr, args);
302}
303
buzbee2cfc6392012-05-07 14:51:40 -0700304llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
305 RegLocation loc)
306{
307 greenland::IntrinsicHelper::IntrinsicId id;
308 if (loc.wide) {
309 if (loc.fp) {
310 id = greenland::IntrinsicHelper::ConstDouble;
311 } else {
312 id = greenland::IntrinsicHelper::ConstLong;
313 }
314 } else {
315 if (loc.fp) {
316 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700317 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700318 id = greenland::IntrinsicHelper::ConstObj;
319 } else {
320 id = greenland::IntrinsicHelper::ConstInt;
321 }
322 }
323 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
324 return cUnit->irb->CreateCall(intr, src);
325}
buzbeeb03f4872012-06-11 15:22:11 -0700326
327void emitPopShadowFrame(CompilationUnit* cUnit)
328{
329 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
330 greenland::IntrinsicHelper::PopShadowFrame);
331 cUnit->irb->CreateCall(intr);
332}
333
buzbee2cfc6392012-05-07 14:51:40 -0700334llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
335 RegLocation loc)
336{
337 greenland::IntrinsicHelper::IntrinsicId id;
338 if (loc.wide) {
339 if (loc.fp) {
340 id = greenland::IntrinsicHelper::CopyDouble;
341 } else {
342 id = greenland::IntrinsicHelper::CopyLong;
343 }
344 } else {
345 if (loc.fp) {
346 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700347 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700348 id = greenland::IntrinsicHelper::CopyObj;
349 } else {
350 id = greenland::IntrinsicHelper::CopyInt;
351 }
352 }
353 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
354 return cUnit->irb->CreateCall(intr, src);
355}
356
buzbee32412962012-06-26 16:27:56 -0700357void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
358{
359 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
360 greenland::IntrinsicHelper::GetException);
361 llvm::Value* res = cUnit->irb->CreateCall(func);
362 defineValue(cUnit, res, rlDest.origSReg);
363}
364
365void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
366{
367 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
368 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
TDYa127f71bf5a2012-07-29 20:09:52 -0700369 greenland::IntrinsicHelper::HLThrowException);
buzbee32412962012-06-26 16:27:56 -0700370 cUnit->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700371}
372
buzbee8fa0fda2012-06-27 15:44:52 -0700373void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
374 greenland::IntrinsicHelper::IntrinsicId id,
375 RegLocation rlSrc)
376{
377 llvm::SmallVector<llvm::Value*, 2> args;
378 args.push_back(cUnit->irb->getInt32(optFlags));
379 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
380 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
381 cUnit->irb->CreateCall(func, args);
382}
383
buzbee76592632012-06-29 15:18:35 -0700384void convertArrayLength(CompilationUnit* cUnit, int optFlags,
385 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700386{
387 llvm::SmallVector<llvm::Value*, 2> args;
388 args.push_back(cUnit->irb->getInt32(optFlags));
389 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
390 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700391 greenland::IntrinsicHelper::OptArrayLength);
buzbee76592632012-06-29 15:18:35 -0700392 llvm::Value* res = cUnit->irb->CreateCall(func, args);
393 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700394}
395
buzbee2cfc6392012-05-07 14:51:40 -0700396void emitSuspendCheck(CompilationUnit* cUnit)
397{
398 greenland::IntrinsicHelper::IntrinsicId id =
399 greenland::IntrinsicHelper::CheckSuspend;
400 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
401 cUnit->irb->CreateCall(intr);
402}
403
404llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
405 llvm::Value* src1, llvm::Value* src2)
406{
407 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700408 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700409 switch(cc) {
410 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
411 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
412 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
413 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
414 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
415 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
416 default: LOG(FATAL) << "Unexpected cc value " << cc;
417 }
418 return res;
419}
420
421void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
422 ConditionCode cc, RegLocation rlSrc1,
423 RegLocation rlSrc2)
424{
425 if (bb->taken->startOffset <= mir->offset) {
426 emitSuspendCheck(cUnit);
427 }
428 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
429 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
430 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
431 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
432 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
433 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700434 // Don't redo the fallthrough branch in the BB driver
435 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700436}
437
438void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
439 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
440{
441 if (bb->taken->startOffset <= mir->offset) {
442 emitSuspendCheck(cUnit);
443 }
444 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
445 llvm::Value* src2;
446 if (rlSrc1.ref) {
447 src2 = cUnit->irb->GetJNull();
448 } else {
449 src2 = cUnit->irb->getInt32(0);
450 }
451 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700452 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
453 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700454 // Don't redo the fallthrough branch in the BB driver
455 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700456}
457
458llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
459 llvm::Value* src1, llvm::Value* src2)
460{
461 greenland::IntrinsicHelper::IntrinsicId id;
462 if (isLong) {
463 if (isDiv) {
464 id = greenland::IntrinsicHelper::DivLong;
465 } else {
466 id = greenland::IntrinsicHelper::RemLong;
467 }
Logan Chien554e6072012-07-23 20:00:01 -0700468 } else {
469 if (isDiv) {
buzbee2cfc6392012-05-07 14:51:40 -0700470 id = greenland::IntrinsicHelper::DivInt;
471 } else {
472 id = greenland::IntrinsicHelper::RemInt;
Logan Chien554e6072012-07-23 20:00:01 -0700473 }
buzbee2cfc6392012-05-07 14:51:40 -0700474 }
475 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
476 llvm::SmallVector<llvm::Value*, 2>args;
477 args.push_back(src1);
478 args.push_back(src2);
479 return cUnit->irb->CreateCall(intr, args);
480}
481
482llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
483 llvm::Value* src1, llvm::Value* src2)
484{
485 llvm::Value* res = NULL;
486 switch(op) {
487 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
488 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700489 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700490 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
491 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
492 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
493 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
494 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
495 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700496 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
497 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
498 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700499 default:
500 LOG(FATAL) << "Invalid op " << op;
501 }
502 return res;
503}
504
505void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
506 RegLocation rlSrc1, RegLocation rlSrc2)
507{
508 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
509 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
510 llvm::Value* res = NULL;
511 switch(op) {
512 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
513 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
514 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
515 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
516 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
517 default:
518 LOG(FATAL) << "Invalid op " << op;
519 }
520 defineValue(cUnit, res, rlDest.origSReg);
521}
522
buzbee2a83e8f2012-07-13 16:42:30 -0700523void convertShift(CompilationUnit* cUnit,
524 greenland::IntrinsicHelper::IntrinsicId id,
525 RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
buzbee4f1181f2012-06-22 13:52:12 -0700526{
buzbee2a83e8f2012-07-13 16:42:30 -0700527 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
528 llvm::SmallVector<llvm::Value*, 2>args;
529 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
530 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
531 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
532 defineValue(cUnit, res, rlDest.origSReg);
533}
534
535void convertShiftLit(CompilationUnit* cUnit,
536 greenland::IntrinsicHelper::IntrinsicId id,
537 RegLocation rlDest, RegLocation rlSrc, int shiftAmount)
538{
539 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
540 llvm::SmallVector<llvm::Value*, 2>args;
541 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
542 args.push_back(cUnit->irb->getInt32(shiftAmount));
543 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700544 defineValue(cUnit, res, rlDest.origSReg);
545}
546
buzbee2cfc6392012-05-07 14:51:40 -0700547void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
548 RegLocation rlSrc1, RegLocation rlSrc2)
549{
550 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
551 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700552 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700553 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
554 defineValue(cUnit, res, rlDest.origSReg);
555}
556
buzbeeb03f4872012-06-11 15:22:11 -0700557void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
558{
559 int index = -1;
560 DCHECK(newVal != NULL);
561 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
562 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
563 if (cUnit->shadowMap[i] == vReg) {
564 index = i;
565 break;
566 }
567 }
TDYa127347166a2012-08-23 12:23:44 -0700568 if (index == -1) {
569 return;
570 }
buzbee6459e7c2012-10-02 14:42:41 -0700571 llvm::Type* ty = newVal->getType();
buzbeeb03f4872012-06-11 15:22:11 -0700572 greenland::IntrinsicHelper::IntrinsicId id =
573 greenland::IntrinsicHelper::SetShadowFrameEntry;
574 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
575 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
buzbee6459e7c2012-10-02 14:42:41 -0700576 // If newVal is a Null pointer, we'll see it here as a const int. Replace
577 if (!ty->isPointerTy()) {
578 // TODO: assert newVal created w/ dex_lang_const_int(0) or dex_lang_const_float(0)
579 newVal = cUnit->irb->GetJNull();
580 }
buzbeeb03f4872012-06-11 15:22:11 -0700581 llvm::Value* args[] = { newVal, tableSlot };
582 cUnit->irb->CreateCall(func, args);
583}
584
buzbee2cfc6392012-05-07 14:51:40 -0700585void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
586 RegLocation rlSrc1, int32_t imm)
587{
588 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
589 llvm::Value* src2 = cUnit->irb->getInt32(imm);
590 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
591 defineValue(cUnit, res, rlDest.origSReg);
592}
593
buzbee101305f2012-06-28 18:00:56 -0700594/*
595 * Process arguments for invoke. Note: this code is also used to
596 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
597 * The requirements are similar.
598 */
buzbee6969d502012-06-15 16:40:31 -0700599void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700600 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700601{
602 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
603 llvm::SmallVector<llvm::Value*, 10> args;
604 // Insert the invokeType
605 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
606 // Insert the method_idx
607 args.push_back(cUnit->irb->getInt32(info->index));
608 // Insert the optimization flags
609 args.push_back(cUnit->irb->getInt32(info->optFlags));
610 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700611 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700612 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
613 args.push_back(val);
614 i += info->args[i].wide ? 2 : 1;
615 }
616 /*
617 * Choose the invoke return type based on actual usage. Note: may
618 * be different than shorty. For example, if a function return value
619 * is not used, we'll treat this as a void invoke.
620 */
621 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700622 if (isFilledNewArray) {
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700623 id = greenland::IntrinsicHelper::HLFilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700624 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700625 id = greenland::IntrinsicHelper::HLInvokeVoid;
626 } else {
627 if (info->result.wide) {
628 if (info->result.fp) {
629 id = greenland::IntrinsicHelper::HLInvokeDouble;
630 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700631 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700632 }
633 } else if (info->result.ref) {
634 id = greenland::IntrinsicHelper::HLInvokeObj;
635 } else if (info->result.fp) {
636 id = greenland::IntrinsicHelper::HLInvokeFloat;
637 } else {
638 id = greenland::IntrinsicHelper::HLInvokeInt;
639 }
640 }
641 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
642 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
643 if (info->result.location != kLocInvalid) {
644 defineValue(cUnit, res, info->result.origSReg);
TDYa127890ea892012-08-22 10:49:42 -0700645 if (info->result.ref) {
buzbeecbd6d442012-11-17 14:11:25 -0800646 setShadowFrameEntry(cUnit, reinterpret_cast<llvm::Value*>
647 (cUnit->llvmValues.elemList[info->result.origSReg]));
TDYa127890ea892012-08-22 10:49:42 -0700648 }
buzbee6969d502012-06-15 16:40:31 -0700649 }
650}
651
buzbee101305f2012-06-28 18:00:56 -0700652void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
653 greenland::IntrinsicHelper::IntrinsicId id,
654 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700655{
buzbee6969d502012-06-15 16:40:31 -0700656 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700657 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700658 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
659 defineValue(cUnit, res, rlDest.origSReg);
660}
661
buzbee101305f2012-06-28 18:00:56 -0700662void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
663 RegLocation rlSrc)
664{
665 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700666 id = greenland::IntrinsicHelper::HLCheckCast;
buzbee101305f2012-06-28 18:00:56 -0700667 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
668 llvm::SmallVector<llvm::Value*, 2> args;
669 args.push_back(cUnit->irb->getInt32(type_idx));
670 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
671 cUnit->irb->CreateCall(intr, args);
672}
673
buzbee8fa0fda2012-06-27 15:44:52 -0700674void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
675 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700676{
677 greenland::IntrinsicHelper::IntrinsicId id;
678 id = greenland::IntrinsicHelper::NewInstance;
679 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
680 llvm::Value* index = cUnit->irb->getInt32(type_idx);
681 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
682 defineValue(cUnit, res, rlDest.origSReg);
683}
684
buzbee8fa0fda2012-06-27 15:44:52 -0700685void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
686 RegLocation rlDest, RegLocation rlSrc)
687{
688 greenland::IntrinsicHelper::IntrinsicId id;
689 id = greenland::IntrinsicHelper::NewArray;
690 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
691 llvm::SmallVector<llvm::Value*, 2> args;
692 args.push_back(cUnit->irb->getInt32(type_idx));
693 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
694 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
695 defineValue(cUnit, res, rlDest.origSReg);
696}
697
698void convertAget(CompilationUnit* cUnit, int optFlags,
699 greenland::IntrinsicHelper::IntrinsicId id,
700 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
701{
702 llvm::SmallVector<llvm::Value*, 3> args;
703 args.push_back(cUnit->irb->getInt32(optFlags));
704 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
705 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
706 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
707 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
708 defineValue(cUnit, res, rlDest.origSReg);
709}
710
711void convertAput(CompilationUnit* cUnit, int optFlags,
712 greenland::IntrinsicHelper::IntrinsicId id,
713 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
714{
715 llvm::SmallVector<llvm::Value*, 4> args;
716 args.push_back(cUnit->irb->getInt32(optFlags));
717 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
718 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
719 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
720 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
721 cUnit->irb->CreateCall(intr, args);
722}
723
buzbee101305f2012-06-28 18:00:56 -0700724void convertIget(CompilationUnit* cUnit, int optFlags,
725 greenland::IntrinsicHelper::IntrinsicId id,
726 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
727{
728 llvm::SmallVector<llvm::Value*, 3> args;
729 args.push_back(cUnit->irb->getInt32(optFlags));
730 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
731 args.push_back(cUnit->irb->getInt32(fieldIndex));
732 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
733 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
734 defineValue(cUnit, res, rlDest.origSReg);
735}
736
737void convertIput(CompilationUnit* cUnit, int optFlags,
738 greenland::IntrinsicHelper::IntrinsicId id,
739 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
740{
741 llvm::SmallVector<llvm::Value*, 4> args;
742 args.push_back(cUnit->irb->getInt32(optFlags));
743 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
744 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
745 args.push_back(cUnit->irb->getInt32(fieldIndex));
746 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
747 cUnit->irb->CreateCall(intr, args);
748}
749
buzbee8fa0fda2012-06-27 15:44:52 -0700750void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
751 RegLocation rlDest, RegLocation rlSrc)
752{
753 greenland::IntrinsicHelper::IntrinsicId id;
754 id = greenland::IntrinsicHelper::InstanceOf;
755 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
756 llvm::SmallVector<llvm::Value*, 2> args;
757 args.push_back(cUnit->irb->getInt32(type_idx));
758 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
759 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
760 defineValue(cUnit, res, rlDest.origSReg);
761}
762
buzbee101305f2012-06-28 18:00:56 -0700763void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
764 RegLocation rlSrc)
765{
766 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
767 cUnit->irb->getInt64Ty());
768 defineValue(cUnit, res, rlDest.origSReg);
769}
770
buzbee76592632012-06-29 15:18:35 -0700771void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
772 RegLocation rlSrc)
773{
774 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
775 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
776 defineValue(cUnit, res, rlDest.origSReg);
777}
778
779void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
780 RegLocation rlSrc)
781{
782 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
783 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
784 defineValue(cUnit, res, rlDest.origSReg);
785}
786
787void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
788 RegLocation rlSrc)
789{
790 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
791 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
792 defineValue(cUnit, res, rlDest.origSReg);
793}
794
795void convertWideComparison(CompilationUnit* cUnit,
796 greenland::IntrinsicHelper::IntrinsicId id,
797 RegLocation rlDest, RegLocation rlSrc1,
798 RegLocation rlSrc2)
799{
800 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
801 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
802 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
803 llvm::SmallVector<llvm::Value*, 2> args;
804 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
805 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
806 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
807 defineValue(cUnit, res, rlDest.origSReg);
808}
809
buzbee101305f2012-06-28 18:00:56 -0700810void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
811 RegLocation rlSrc,
812 greenland::IntrinsicHelper::IntrinsicId id)
813{
814 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700815 llvm::Value* res =
816 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
817 defineValue(cUnit, res, rlDest.origSReg);
818}
819
820void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
821 RegLocation rlSrc)
822{
823 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
824 defineValue(cUnit, res, rlDest.origSReg);
825}
826
827void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
828 RegLocation rlSrc)
829{
830 llvm::Value* res =
831 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
832 defineValue(cUnit, res, rlDest.origSReg);
833}
834
TDYa1274ec8ccd2012-08-11 07:04:57 -0700835void convertFPToInt(CompilationUnit* cUnit,
836 greenland::IntrinsicHelper::IntrinsicId id,
837 RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700838 RegLocation rlSrc)
839{
TDYa1274ec8ccd2012-08-11 07:04:57 -0700840 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
841 llvm::Value* res = cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
buzbee76592632012-06-29 15:18:35 -0700842 defineValue(cUnit, res, rlDest.origSReg);
843}
844
845
846void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
847 RegLocation rlSrc)
848{
849 llvm::Value* res =
850 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
851 defineValue(cUnit, res, rlDest.origSReg);
852}
853
854void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
855 RegLocation rlSrc)
856{
857 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
858 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700859 defineValue(cUnit, res, rlDest.origSReg);
860}
861
buzbee2cfc6392012-05-07 14:51:40 -0700862/*
863 * Target-independent code generation. Use only high-level
864 * load/store utilities here, or target-dependent genXX() handlers
865 * when necessary.
866 */
867bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
868 llvm::BasicBlock* llvmBB, LIR* labelList)
869{
870 bool res = false; // Assume success
871 RegLocation rlSrc[3];
872 RegLocation rlDest = badLoc;
buzbee2cfc6392012-05-07 14:51:40 -0700873 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbeecbd6d442012-11-17 14:11:25 -0800874 int opVal = opcode;
buzbee6969d502012-06-15 16:40:31 -0700875 uint32_t vB = mir->dalvikInsn.vB;
876 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700877 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700878
buzbeeb03f4872012-06-11 15:22:11 -0700879 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700880
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700881 if (cUnit->printMe) {
buzbeecbd6d442012-11-17 14:11:25 -0800882 if (opVal < kMirOpFirst) {
883 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x" << std::hex << opVal;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700884 } else {
buzbeecbd6d442012-11-17 14:11:25 -0800885 LOG(INFO) << extendedMIROpNames[opVal - kMirOpFirst] << " 0x" << std::hex << opVal;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700886 }
887 }
888
buzbee2cfc6392012-05-07 14:51:40 -0700889 /* Prep Src and Dest locations */
890 int nextSreg = 0;
891 int nextLoc = 0;
892 int attrs = oatDataFlowAttributes[opcode];
893 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
894 if (attrs & DF_UA) {
895 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700896 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700897 nextSreg+= 2;
898 } else {
899 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
900 nextSreg++;
901 }
902 }
903 if (attrs & DF_UB) {
904 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700905 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700906 nextSreg+= 2;
907 } else {
908 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
909 nextSreg++;
910 }
911 }
912 if (attrs & DF_UC) {
913 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700914 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700915 } else {
916 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
917 }
918 }
919 if (attrs & DF_DA) {
920 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700921 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700922 } else {
buzbee15bf9802012-06-12 17:49:27 -0700923 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700924 if (rlDest.ref) {
925 objectDefinition = true;
926 }
buzbee2cfc6392012-05-07 14:51:40 -0700927 }
928 }
929
930 switch (opcode) {
931 case Instruction::NOP:
932 break;
933
934 case Instruction::MOVE:
935 case Instruction::MOVE_OBJECT:
936 case Instruction::MOVE_16:
937 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700938 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700939 case Instruction::MOVE_FROM16:
940 case Instruction::MOVE_WIDE:
941 case Instruction::MOVE_WIDE_16:
942 case Instruction::MOVE_WIDE_FROM16: {
943 /*
944 * Moves/copies are meaningless in pure SSA register form,
945 * but we need to preserve them for the conversion back into
946 * MIR (at least until we stop using the Dalvik register maps).
947 * Insert a dummy intrinsic copy call, which will be recognized
948 * by the quick path and removed by the portable path.
949 */
950 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
951 llvm::Value* res = emitCopy(cUnit, src, rlDest);
952 defineValue(cUnit, res, rlDest.origSReg);
953 }
954 break;
955
956 case Instruction::CONST:
957 case Instruction::CONST_4:
958 case Instruction::CONST_16: {
TDYa127347166a2012-08-23 12:23:44 -0700959 if (vB == 0) {
960 objectDefinition = true;
961 }
buzbee6969d502012-06-15 16:40:31 -0700962 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700963 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
964 defineValue(cUnit, res, rlDest.origSReg);
965 }
966 break;
967
968 case Instruction::CONST_WIDE_16:
969 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700970 // Sign extend to 64 bits
971 int64_t imm = static_cast<int32_t>(vB);
972 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700973 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
974 defineValue(cUnit, res, rlDest.origSReg);
975 }
976 break;
977
978 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700979 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700980 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
981 defineValue(cUnit, res, rlDest.origSReg);
982 }
983 break;
984
985 case Instruction::CONST_WIDE: {
986 llvm::Constant* immValue =
987 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
988 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
989 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700990 }
991 break;
buzbee2cfc6392012-05-07 14:51:40 -0700992 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700993 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700994 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
995 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
996 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700997 }
998 break;
999
buzbee8fa0fda2012-06-27 15:44:52 -07001000 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -07001001 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -07001002 rlSrc[0]);
1003 break;
1004 case Instruction::SPUT:
1005 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -07001006 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -07001007 rlSrc[0]);
1008 } else {
buzbee76592632012-06-29 15:18:35 -07001009 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001010 }
1011 break;
1012 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -07001013 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -07001014 rlSrc[0]);
1015 break;
1016 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -07001017 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001018 break;
1019 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -07001020 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001021 break;
1022 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -07001023 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001024 break;
1025 case Instruction::SPUT_WIDE:
1026 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -07001027 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -07001028 rlSrc[0]);
1029 } else {
buzbee76592632012-06-29 15:18:35 -07001030 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -07001031 rlSrc[0]);
1032 }
1033 break;
1034
1035 case Instruction::SGET_OBJECT:
1036 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
1037 break;
1038 case Instruction::SGET:
1039 if (rlDest.fp) {
1040 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
1041 } else {
1042 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
1043 }
1044 break;
1045 case Instruction::SGET_BOOLEAN:
1046 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
1047 break;
1048 case Instruction::SGET_BYTE:
1049 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
1050 break;
1051 case Instruction::SGET_CHAR:
1052 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
1053 break;
1054 case Instruction::SGET_SHORT:
1055 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
1056 break;
1057 case Instruction::SGET_WIDE:
1058 if (rlDest.fp) {
1059 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
1060 rlDest);
1061 } else {
1062 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001063 }
1064 break;
buzbee2cfc6392012-05-07 14:51:40 -07001065
1066 case Instruction::RETURN_WIDE:
1067 case Instruction::RETURN:
1068 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -07001069 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001070 emitSuspendCheck(cUnit);
1071 }
buzbeeb03f4872012-06-11 15:22:11 -07001072 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001073 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
1074 bb->hasReturn = true;
1075 }
1076 break;
1077
1078 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001079 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001080 emitSuspendCheck(cUnit);
1081 }
buzbeeb03f4872012-06-11 15:22:11 -07001082 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001083 cUnit->irb->CreateRetVoid();
1084 bb->hasReturn = true;
1085 }
1086 break;
1087
1088 case Instruction::IF_EQ:
1089 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1090 break;
1091 case Instruction::IF_NE:
1092 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1093 break;
1094 case Instruction::IF_LT:
1095 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1096 break;
1097 case Instruction::IF_GE:
1098 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1099 break;
1100 case Instruction::IF_GT:
1101 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1102 break;
1103 case Instruction::IF_LE:
1104 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1105 break;
1106 case Instruction::IF_EQZ:
1107 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1108 break;
1109 case Instruction::IF_NEZ:
1110 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1111 break;
1112 case Instruction::IF_LTZ:
1113 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1114 break;
1115 case Instruction::IF_GEZ:
1116 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1117 break;
1118 case Instruction::IF_GTZ:
1119 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1120 break;
1121 case Instruction::IF_LEZ:
1122 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1123 break;
1124
1125 case Instruction::GOTO:
1126 case Instruction::GOTO_16:
1127 case Instruction::GOTO_32: {
1128 if (bb->taken->startOffset <= bb->startOffset) {
1129 emitSuspendCheck(cUnit);
1130 }
1131 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1132 }
1133 break;
1134
1135 case Instruction::ADD_LONG:
1136 case Instruction::ADD_LONG_2ADDR:
1137 case Instruction::ADD_INT:
1138 case Instruction::ADD_INT_2ADDR:
1139 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1140 break;
1141 case Instruction::SUB_LONG:
1142 case Instruction::SUB_LONG_2ADDR:
1143 case Instruction::SUB_INT:
1144 case Instruction::SUB_INT_2ADDR:
1145 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1146 break;
1147 case Instruction::MUL_LONG:
1148 case Instruction::MUL_LONG_2ADDR:
1149 case Instruction::MUL_INT:
1150 case Instruction::MUL_INT_2ADDR:
1151 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1152 break;
1153 case Instruction::DIV_LONG:
1154 case Instruction::DIV_LONG_2ADDR:
1155 case Instruction::DIV_INT:
1156 case Instruction::DIV_INT_2ADDR:
1157 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1158 break;
1159 case Instruction::REM_LONG:
1160 case Instruction::REM_LONG_2ADDR:
1161 case Instruction::REM_INT:
1162 case Instruction::REM_INT_2ADDR:
1163 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1164 break;
1165 case Instruction::AND_LONG:
1166 case Instruction::AND_LONG_2ADDR:
1167 case Instruction::AND_INT:
1168 case Instruction::AND_INT_2ADDR:
1169 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1170 break;
1171 case Instruction::OR_LONG:
1172 case Instruction::OR_LONG_2ADDR:
1173 case Instruction::OR_INT:
1174 case Instruction::OR_INT_2ADDR:
1175 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1176 break;
1177 case Instruction::XOR_LONG:
1178 case Instruction::XOR_LONG_2ADDR:
1179 case Instruction::XOR_INT:
1180 case Instruction::XOR_INT_2ADDR:
1181 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1182 break;
1183 case Instruction::SHL_LONG:
1184 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001185 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1186 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001187 break;
buzbee2cfc6392012-05-07 14:51:40 -07001188 case Instruction::SHL_INT:
1189 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001190 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1191 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001192 break;
1193 case Instruction::SHR_LONG:
1194 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001195 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1196 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001197 break;
buzbee2cfc6392012-05-07 14:51:40 -07001198 case Instruction::SHR_INT:
1199 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001200 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1201 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001202 break;
1203 case Instruction::USHR_LONG:
1204 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001205 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1206 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001207 break;
buzbee2cfc6392012-05-07 14:51:40 -07001208 case Instruction::USHR_INT:
1209 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001210 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1211 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001212 break;
1213
1214 case Instruction::ADD_INT_LIT16:
1215 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001216 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001217 break;
1218 case Instruction::RSUB_INT:
1219 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001220 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001221 break;
1222 case Instruction::MUL_INT_LIT16:
1223 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001224 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001225 break;
1226 case Instruction::DIV_INT_LIT16:
1227 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001228 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001229 break;
1230 case Instruction::REM_INT_LIT16:
1231 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001232 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001233 break;
1234 case Instruction::AND_INT_LIT16:
1235 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001236 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001237 break;
1238 case Instruction::OR_INT_LIT16:
1239 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001240 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001241 break;
1242 case Instruction::XOR_INT_LIT16:
1243 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001244 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001245 break;
1246 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001247 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1248 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001249 break;
1250 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001251 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1252 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001253 break;
1254 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001255 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1256 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001257 break;
1258
1259 case Instruction::ADD_FLOAT:
1260 case Instruction::ADD_FLOAT_2ADDR:
1261 case Instruction::ADD_DOUBLE:
1262 case Instruction::ADD_DOUBLE_2ADDR:
1263 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1264 break;
1265
1266 case Instruction::SUB_FLOAT:
1267 case Instruction::SUB_FLOAT_2ADDR:
1268 case Instruction::SUB_DOUBLE:
1269 case Instruction::SUB_DOUBLE_2ADDR:
1270 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1271 break;
1272
1273 case Instruction::MUL_FLOAT:
1274 case Instruction::MUL_FLOAT_2ADDR:
1275 case Instruction::MUL_DOUBLE:
1276 case Instruction::MUL_DOUBLE_2ADDR:
1277 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1278 break;
1279
1280 case Instruction::DIV_FLOAT:
1281 case Instruction::DIV_FLOAT_2ADDR:
1282 case Instruction::DIV_DOUBLE:
1283 case Instruction::DIV_DOUBLE_2ADDR:
1284 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1285 break;
1286
1287 case Instruction::REM_FLOAT:
1288 case Instruction::REM_FLOAT_2ADDR:
1289 case Instruction::REM_DOUBLE:
1290 case Instruction::REM_DOUBLE_2ADDR:
1291 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1292 break;
1293
buzbee6969d502012-06-15 16:40:31 -07001294 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001295 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1296 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001297 break;
1298 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001299 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1300 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001301 break;
1302
1303 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001304 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1305 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001306 break;
1307 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001308 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1309 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001310 break;
1311
1312 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001313 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1314 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001315 break;
1316 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001317 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1318 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001319 break;
1320
1321 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001322 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1323 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001324 break;
1325 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001326 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1327 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001328 break;
1329
1330 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001331 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1332 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001333 break;
1334 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001335 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1336 false /* NewFilledArray */);
1337 break;
1338 case Instruction::FILLED_NEW_ARRAY:
1339 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1340 true /* NewFilledArray */);
1341 break;
1342 case Instruction::FILLED_NEW_ARRAY_RANGE:
1343 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1344 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001345 break;
1346
1347 case Instruction::CONST_STRING:
1348 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001349 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1350 rlDest);
1351 break;
1352
1353 case Instruction::CONST_CLASS:
1354 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1355 rlDest);
1356 break;
1357
1358 case Instruction::CHECK_CAST:
1359 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001360 break;
1361
buzbee4f1181f2012-06-22 13:52:12 -07001362 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001363 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001364 break;
1365
buzbee32412962012-06-26 16:27:56 -07001366 case Instruction::MOVE_EXCEPTION:
1367 convertMoveException(cUnit, rlDest);
1368 break;
1369
1370 case Instruction::THROW:
1371 convertThrow(cUnit, rlSrc[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001372 /*
1373 * If this throw is standalone, terminate.
1374 * If it might rethrow, force termination
1375 * of the following block.
1376 */
1377 if (bb->fallThrough == NULL) {
1378 cUnit->irb->CreateUnreachable();
1379 } else {
1380 bb->fallThrough->fallThrough = NULL;
1381 bb->fallThrough->taken = NULL;
1382 }
buzbee32412962012-06-26 16:27:56 -07001383 break;
1384
buzbee2cfc6392012-05-07 14:51:40 -07001385 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001386 case Instruction::MOVE_RESULT:
1387 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001388 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001389 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001390 */
jeffhao9a4f0032012-08-30 16:17:40 -07001391 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001392 break;
1393
1394 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001395 convertMonitorEnterExit(cUnit, optFlags,
1396 greenland::IntrinsicHelper::MonitorEnter,
1397 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001398 break;
1399
1400 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001401 convertMonitorEnterExit(cUnit, optFlags,
1402 greenland::IntrinsicHelper::MonitorExit,
1403 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001404 break;
1405
1406 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001407 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001408 break;
1409
1410 case Instruction::NEW_ARRAY:
1411 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1412 break;
1413
1414 case Instruction::INSTANCE_OF:
1415 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1416 break;
1417
1418 case Instruction::AGET:
1419 if (rlDest.fp) {
1420 convertAget(cUnit, optFlags,
1421 greenland::IntrinsicHelper::HLArrayGetFloat,
1422 rlDest, rlSrc[0], rlSrc[1]);
1423 } else {
1424 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1425 rlDest, rlSrc[0], rlSrc[1]);
1426 }
1427 break;
1428 case Instruction::AGET_OBJECT:
1429 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1430 rlDest, rlSrc[0], rlSrc[1]);
1431 break;
1432 case Instruction::AGET_BOOLEAN:
1433 convertAget(cUnit, optFlags,
1434 greenland::IntrinsicHelper::HLArrayGetBoolean,
1435 rlDest, rlSrc[0], rlSrc[1]);
1436 break;
1437 case Instruction::AGET_BYTE:
1438 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1439 rlDest, rlSrc[0], rlSrc[1]);
1440 break;
1441 case Instruction::AGET_CHAR:
1442 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1443 rlDest, rlSrc[0], rlSrc[1]);
1444 break;
1445 case Instruction::AGET_SHORT:
1446 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1447 rlDest, rlSrc[0], rlSrc[1]);
1448 break;
1449 case Instruction::AGET_WIDE:
1450 if (rlDest.fp) {
1451 convertAget(cUnit, optFlags,
1452 greenland::IntrinsicHelper::HLArrayGetDouble,
1453 rlDest, rlSrc[0], rlSrc[1]);
1454 } else {
1455 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1456 rlDest, rlSrc[0], rlSrc[1]);
1457 }
1458 break;
1459
1460 case Instruction::APUT:
1461 if (rlSrc[0].fp) {
1462 convertAput(cUnit, optFlags,
1463 greenland::IntrinsicHelper::HLArrayPutFloat,
1464 rlSrc[0], rlSrc[1], rlSrc[2]);
1465 } else {
1466 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1467 rlSrc[0], rlSrc[1], rlSrc[2]);
1468 }
1469 break;
1470 case Instruction::APUT_OBJECT:
1471 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1472 rlSrc[0], rlSrc[1], rlSrc[2]);
1473 break;
1474 case Instruction::APUT_BOOLEAN:
1475 convertAput(cUnit, optFlags,
1476 greenland::IntrinsicHelper::HLArrayPutBoolean,
1477 rlSrc[0], rlSrc[1], rlSrc[2]);
1478 break;
1479 case Instruction::APUT_BYTE:
1480 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1481 rlSrc[0], rlSrc[1], rlSrc[2]);
1482 break;
1483 case Instruction::APUT_CHAR:
1484 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1485 rlSrc[0], rlSrc[1], rlSrc[2]);
1486 break;
1487 case Instruction::APUT_SHORT:
1488 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1489 rlSrc[0], rlSrc[1], rlSrc[2]);
1490 break;
1491 case Instruction::APUT_WIDE:
1492 if (rlSrc[0].fp) {
1493 convertAput(cUnit, optFlags,
1494 greenland::IntrinsicHelper::HLArrayPutDouble,
1495 rlSrc[0], rlSrc[1], rlSrc[2]);
1496 } else {
1497 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1498 rlSrc[0], rlSrc[1], rlSrc[2]);
1499 }
1500 break;
1501
buzbee101305f2012-06-28 18:00:56 -07001502 case Instruction::IGET:
1503 if (rlDest.fp) {
1504 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001505 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001506 } else {
1507 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001508 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001509 }
buzbee2cfc6392012-05-07 14:51:40 -07001510 break;
buzbee101305f2012-06-28 18:00:56 -07001511 case Instruction::IGET_OBJECT:
1512 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001513 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001514 break;
1515 case Instruction::IGET_BOOLEAN:
1516 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001517 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001518 break;
1519 case Instruction::IGET_BYTE:
1520 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001521 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001522 break;
1523 case Instruction::IGET_CHAR:
1524 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001525 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001526 break;
1527 case Instruction::IGET_SHORT:
1528 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001529 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001530 break;
1531 case Instruction::IGET_WIDE:
1532 if (rlDest.fp) {
1533 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001534 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001535 } else {
1536 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001537 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001538 }
1539 break;
1540 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001541 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001542 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1543 rlSrc[0], rlSrc[1], vC);
1544 } else {
1545 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1546 rlSrc[0], rlSrc[1], vC);
1547 }
1548 break;
1549 case Instruction::IPUT_OBJECT:
1550 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1551 rlSrc[0], rlSrc[1], vC);
1552 break;
1553 case Instruction::IPUT_BOOLEAN:
1554 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1555 rlSrc[0], rlSrc[1], vC);
1556 break;
1557 case Instruction::IPUT_BYTE:
1558 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1559 rlSrc[0], rlSrc[1], vC);
1560 break;
1561 case Instruction::IPUT_CHAR:
1562 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1563 rlSrc[0], rlSrc[1], vC);
1564 break;
1565 case Instruction::IPUT_SHORT:
1566 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1567 rlSrc[0], rlSrc[1], vC);
1568 break;
1569 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001570 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001571 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1572 rlSrc[0], rlSrc[1], vC);
1573 } else {
1574 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1575 rlSrc[0], rlSrc[1], vC);
1576 }
buzbee2cfc6392012-05-07 14:51:40 -07001577 break;
1578
1579 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001580 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001581 break;
1582
buzbee76592632012-06-29 15:18:35 -07001583 case Instruction::LONG_TO_INT:
1584 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1585 break;
1586
buzbee101305f2012-06-28 18:00:56 -07001587 case Instruction::INT_TO_LONG:
1588 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001589 break;
1590
buzbee101305f2012-06-28 18:00:56 -07001591 case Instruction::INT_TO_CHAR:
1592 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1593 greenland::IntrinsicHelper::IntToChar);
1594 break;
1595 case Instruction::INT_TO_BYTE:
1596 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1597 greenland::IntrinsicHelper::IntToByte);
1598 break;
1599 case Instruction::INT_TO_SHORT:
1600 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1601 greenland::IntrinsicHelper::IntToShort);
1602 break;
1603
buzbee76592632012-06-29 15:18:35 -07001604 case Instruction::INT_TO_FLOAT:
1605 case Instruction::LONG_TO_FLOAT:
1606 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001607 break;
1608
buzbee76592632012-06-29 15:18:35 -07001609 case Instruction::INT_TO_DOUBLE:
1610 case Instruction::LONG_TO_DOUBLE:
1611 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001612 break;
1613
buzbee76592632012-06-29 15:18:35 -07001614 case Instruction::FLOAT_TO_DOUBLE:
1615 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001616 break;
1617
buzbee76592632012-06-29 15:18:35 -07001618 case Instruction::DOUBLE_TO_FLOAT:
1619 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001620 break;
1621
1622 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001623 case Instruction::NEG_INT:
1624 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001625 break;
1626
1627 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001628 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001629 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001630 break;
1631
buzbee76592632012-06-29 15:18:35 -07001632 case Instruction::NOT_LONG:
1633 case Instruction::NOT_INT:
1634 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001635 break;
1636
buzbee2cfc6392012-05-07 14:51:40 -07001637 case Instruction::FLOAT_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001638 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2I, rlDest, rlSrc[0]);
1639 break;
1640
buzbee2cfc6392012-05-07 14:51:40 -07001641 case Instruction::DOUBLE_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001642 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2I, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001643 break;
1644
buzbee76592632012-06-29 15:18:35 -07001645 case Instruction::FLOAT_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001646 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2L, rlDest, rlSrc[0]);
1647 break;
1648
buzbee76592632012-06-29 15:18:35 -07001649 case Instruction::DOUBLE_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001650 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2L, rlDest, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001651 break;
1652
1653 case Instruction::CMPL_FLOAT:
1654 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1655 rlDest, rlSrc[0], rlSrc[1]);
1656 break;
1657 case Instruction::CMPG_FLOAT:
1658 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1659 rlDest, rlSrc[0], rlSrc[1]);
1660 break;
1661 case Instruction::CMPL_DOUBLE:
1662 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1663 rlDest, rlSrc[0], rlSrc[1]);
1664 break;
1665 case Instruction::CMPG_DOUBLE:
1666 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1667 rlDest, rlSrc[0], rlSrc[1]);
1668 break;
1669 case Instruction::CMP_LONG:
1670 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1671 rlDest, rlSrc[0], rlSrc[1]);
1672 break;
1673
buzbee76592632012-06-29 15:18:35 -07001674 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001675 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001676 break;
1677
1678 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001679 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001680 break;
buzbee2cfc6392012-05-07 14:51:40 -07001681
1682 default:
buzbee32412962012-06-26 16:27:56 -07001683 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001684 res = true;
1685 }
buzbeeb03f4872012-06-11 15:22:11 -07001686 if (objectDefinition) {
buzbeecbd6d442012-11-17 14:11:25 -08001687 setShadowFrameEntry(cUnit, reinterpret_cast<llvm::Value*>
1688 (cUnit->llvmValues.elemList[rlDest.origSReg]));
buzbeeb03f4872012-06-11 15:22:11 -07001689 }
buzbee2cfc6392012-05-07 14:51:40 -07001690 return res;
1691}
1692
1693/* Extended MIR instructions like PHI */
1694void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1695 llvm::BasicBlock* llvmBB)
1696{
1697
buzbeecbd6d442012-11-17 14:11:25 -08001698 switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
buzbee2cfc6392012-05-07 14:51:40 -07001699 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001700 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001701 /*
1702 * The Art compiler's Phi nodes only handle 32-bit operands,
1703 * representing wide values using a matched set of Phi nodes
1704 * for the lower and upper halves. In the llvm world, we only
1705 * want a single Phi for wides. Here we will simply discard
1706 * the Phi node representing the high word.
1707 */
1708 if (rlDest.highWord) {
1709 return; // No Phi node - handled via low word
1710 }
buzbeecbd6d442012-11-17 14:11:25 -08001711 int* incoming = reinterpret_cast<int*>(mir->dalvikInsn.vB);
buzbee2cfc6392012-05-07 14:51:40 -07001712 llvm::Type* phiType =
1713 llvmTypeFromLocRec(cUnit, rlDest);
1714 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1715 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1716 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001717 // Don't check width here.
1718 loc = oatGetRawSrc(cUnit, mir, i);
1719 DCHECK_EQ(rlDest.wide, loc.wide);
1720 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1721 DCHECK_EQ(rlDest.fp, loc.fp);
1722 DCHECK_EQ(rlDest.core, loc.core);
1723 DCHECK_EQ(rlDest.ref, loc.ref);
buzbeed1643e42012-09-05 14:06:51 -07001724 SafeMap<unsigned int, unsigned int>::iterator it;
1725 it = cUnit->blockIdMap.find(incoming[i]);
1726 DCHECK(it != cUnit->blockIdMap.end());
buzbee2cfc6392012-05-07 14:51:40 -07001727 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
buzbeed1643e42012-09-05 14:06:51 -07001728 getLLVMBlock(cUnit, it->second));
buzbee2cfc6392012-05-07 14:51:40 -07001729 }
1730 defineValue(cUnit, phi, rlDest.origSReg);
1731 break;
1732 }
1733 case kMirOpCopy: {
1734 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1735 break;
1736 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001737 case kMirOpNop:
1738 if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
1739 (bb->fallThrough == NULL)) {
1740 cUnit->irb->CreateUnreachable();
1741 }
1742 break;
1743
buzbeeb046e162012-10-30 15:48:42 -07001744 // TODO: need GBC intrinsic to take advantage of fused operations
buzbee2cfc6392012-05-07 14:51:40 -07001745 case kMirOpFusedCmplFloat:
buzbeeb046e162012-10-30 15:48:42 -07001746 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpFloat unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001747 break;
1748 case kMirOpFusedCmpgFloat:
buzbeeb046e162012-10-30 15:48:42 -07001749 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmgFloat unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001750 break;
1751 case kMirOpFusedCmplDouble:
buzbeeb046e162012-10-30 15:48:42 -07001752 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmplDouble unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001753 break;
1754 case kMirOpFusedCmpgDouble:
buzbeeb046e162012-10-30 15:48:42 -07001755 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpgDouble unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001756 break;
1757 case kMirOpFusedCmpLong:
buzbeeb046e162012-10-30 15:48:42 -07001758 UNIMPLEMENTED(FATAL) << "kMirOpLongCmpBranch unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001759 break;
buzbee2cfc6392012-05-07 14:51:40 -07001760 default:
1761 break;
1762 }
1763}
1764
1765void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1766{
1767 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001768 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001769 arrayRef.push_back(cUnit->irb->getInt32(offset));
1770 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1771 cUnit->irb->SetDexOffset(node);
1772}
1773
1774// Attach method info as metadata to special intrinsic
1775void setMethodInfo(CompilationUnit* cUnit)
1776{
1777 // We don't want dex offset on this
1778 cUnit->irb->SetDexOffset(NULL);
1779 greenland::IntrinsicHelper::IntrinsicId id;
1780 id = greenland::IntrinsicHelper::MethodInfo;
1781 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1782 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1783 llvm::SmallVector<llvm::Value*, 2> regInfo;
1784 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1785 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1786 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1787 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1788 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1789 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1790 inst->setMetadata("RegInfo", regInfoNode);
1791 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1792 llvm::SmallVector<llvm::Value*, 50> pmap;
1793 for (int i = 0; i < promoSize; i++) {
1794 PromotionMap* p = &cUnit->promotionMap[i];
1795 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1796 ((p->fpReg & 0xff) << 16) |
1797 ((p->coreReg & 0xff) << 8) |
1798 ((p->fpLocation & 0xf) << 4) |
1799 (p->coreLocation & 0xf);
1800 pmap.push_back(cUnit->irb->getInt32(mapData));
1801 }
1802 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1803 inst->setMetadata("PromotionMap", mapNode);
1804 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1805}
1806
1807/* Handle the content in each basic block */
1808bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1809{
buzbeed1643e42012-09-05 14:06:51 -07001810 if (bb->blockType == kDead) return false;
buzbee2cfc6392012-05-07 14:51:40 -07001811 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
buzbeef5f5a122012-09-21 13:57:36 -07001812 if (llvmBB == NULL) {
1813 CHECK(bb->blockType == kExitBlock);
1814 } else {
1815 cUnit->irb->SetInsertPoint(llvmBB);
1816 setDexOffset(cUnit, bb->startOffset);
1817 }
buzbee2cfc6392012-05-07 14:51:40 -07001818
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001819 if (cUnit->printMe) {
1820 LOG(INFO) << "................................";
1821 LOG(INFO) << "Block id " << bb->id;
1822 if (llvmBB != NULL) {
1823 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1824 } else {
1825 LOG(INFO) << "llvmBB is NULL";
1826 }
1827 }
1828
buzbee2cfc6392012-05-07 14:51:40 -07001829 if (bb->blockType == kEntryBlock) {
1830 setMethodInfo(cUnit);
buzbeecbd6d442012-11-17 14:11:25 -08001831 bool *canBeRef = static_cast<bool*>(oatNew(cUnit, sizeof(bool) * cUnit->numDalvikRegisters,
1832 true, kAllocMisc));
buzbeeb03f4872012-06-11 15:22:11 -07001833 for (int i = 0; i < cUnit->numSSARegs; i++) {
buzbee6ec5e232012-09-20 15:50:03 -07001834 int vReg = SRegToVReg(cUnit, i);
1835 if (vReg > SSA_METHOD_BASEREG) {
1836 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1837 }
buzbeeb03f4872012-06-11 15:22:11 -07001838 }
1839 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1840 if (canBeRef[i]) {
1841 cUnit->numShadowFrameEntries++;
1842 }
1843 }
1844 if (cUnit->numShadowFrameEntries > 0) {
buzbeecbd6d442012-11-17 14:11:25 -08001845 cUnit->shadowMap = static_cast<int*>(oatNew(cUnit, sizeof(int) * cUnit->numShadowFrameEntries,
1846 true, kAllocMisc));
buzbeeb03f4872012-06-11 15:22:11 -07001847 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1848 if (canBeRef[i]) {
1849 cUnit->shadowMap[j++] = i;
1850 }
1851 }
buzbeeb03f4872012-06-11 15:22:11 -07001852 }
Shih-wei Liao569daf12012-08-10 23:22:33 -07001853 greenland::IntrinsicHelper::IntrinsicId id =
1854 greenland::IntrinsicHelper::AllocaShadowFrame;
1855 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1856 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
TDYa1278e950c12012-11-02 09:58:19 -07001857 llvm::Value* dalvikRegs = cUnit->irb->getInt32(cUnit->numDalvikRegisters);
1858 llvm::Value* args[] = { entries, dalvikRegs };
1859 cUnit->irb->CreateCall(func, args);
buzbee2cfc6392012-05-07 14:51:40 -07001860 } else if (bb->blockType == kExitBlock) {
1861 /*
1862 * Because of the differences between how MIR/LIR and llvm handle exit
1863 * blocks, we won't explicitly covert them. On the llvm-to-lir
1864 * path, it will need to be regenereated.
1865 */
1866 return false;
buzbee6969d502012-06-15 16:40:31 -07001867 } else if (bb->blockType == kExceptionHandling) {
1868 /*
1869 * Because we're deferring null checking, delete the associated empty
1870 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001871 */
1872 llvmBB->eraseFromParent();
1873 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001874 }
1875
1876 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1877
1878 setDexOffset(cUnit, mir->offset);
1879
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001880 int opcode = mir->dalvikInsn.opcode;
1881 Instruction::Format dalvikFormat =
1882 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001883
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001884 if (opcode == kMirOpCheck) {
1885 // Combine check and work halves of throwing instruction.
1886 MIR* workHalf = mir->meta.throwInsn;
1887 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
1888 opcode = mir->dalvikInsn.opcode;
1889 SSARepresentation* ssaRep = workHalf->ssaRep;
1890 workHalf->ssaRep = mir->ssaRep;
1891 mir->ssaRep = ssaRep;
1892 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1893 if (bb->successorBlockList.blockListType == kCatch) {
1894 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
1895 greenland::IntrinsicHelper::CatchTargets);
1896 llvm::Value* switchKey =
1897 cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
1898 GrowableListIterator iter;
1899 oatGrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
1900 // New basic block to use for work half
1901 llvm::BasicBlock* workBB =
1902 llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
1903 llvm::SwitchInst* sw =
1904 cUnit->irb->CreateSwitch(switchKey, workBB,
1905 bb->successorBlockList.blocks.numUsed);
1906 while (true) {
1907 SuccessorBlockInfo *successorBlockInfo =
buzbeecbd6d442012-11-17 14:11:25 -08001908 reinterpret_cast<SuccessorBlockInfo*>(oatGrowableListIteratorNext(&iter));
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001909 if (successorBlockInfo == NULL) break;
1910 llvm::BasicBlock *target =
1911 getLLVMBlock(cUnit, successorBlockInfo->block->id);
1912 int typeIndex = successorBlockInfo->key;
1913 sw->addCase(cUnit->irb->getInt32(typeIndex), target);
1914 }
1915 llvmBB = workBB;
1916 cUnit->irb->SetInsertPoint(llvmBB);
1917 }
1918 }
1919
1920 if (opcode >= kMirOpFirst) {
buzbee2cfc6392012-05-07 14:51:40 -07001921 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1922 continue;
1923 }
1924
1925 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1926 NULL /* labelList */);
1927 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001928 Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001929 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001930 mir->offset, opcode,
buzbee2cfc6392012-05-07 14:51:40 -07001931 Instruction::Name(dalvikOpcode),
1932 dalvikFormat);
1933 }
1934 }
1935
buzbee4be777b2012-07-12 14:38:18 -07001936 if (bb->blockType == kEntryBlock) {
1937 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1938 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001939 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1940 }
1941
1942 return false;
1943}
1944
buzbee4f4dfc72012-07-02 14:54:44 -07001945char remapShorty(char shortyType) {
1946 /*
1947 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1948 * and longs/doubles are represented as a pair of registers. When sub-word
1949 * arguments (and method results) are passed, they are extended to Dalvik
1950 * virtual register containers. Because llvm is picky about type consistency,
1951 * we must either cast the "real" type to 32-bit container multiple Dalvik
1952 * register types, or always use the expanded values.
1953 * Here, we're doing the latter. We map the shorty signature to container
1954 * types (which is valid so long as we always do a real expansion of passed
1955 * arguments and field loads).
1956 */
1957 switch(shortyType) {
1958 case 'Z' : shortyType = 'I'; break;
1959 case 'B' : shortyType = 'I'; break;
1960 case 'S' : shortyType = 'I'; break;
1961 case 'C' : shortyType = 'I'; break;
1962 default: break;
1963 }
1964 return shortyType;
1965}
1966
buzbee2cfc6392012-05-07 14:51:40 -07001967llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1968
1969 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001970 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001971 greenland::kAccurate);
1972
1973 // Get argument type
1974 std::vector<llvm::Type*> args_type;
1975
1976 // method object
1977 args_type.push_back(cUnit->irb->GetJMethodTy());
1978
1979 // Do we have a "this"?
1980 if ((cUnit->access_flags & kAccStatic) == 0) {
1981 args_type.push_back(cUnit->irb->GetJObjectTy());
1982 }
1983
1984 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001985 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001986 greenland::kAccurate));
1987 }
1988
1989 return llvm::FunctionType::get(ret_type, args_type, false);
1990}
1991
1992bool createFunction(CompilationUnit* cUnit) {
1993 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1994 /* with_signature */ false));
1995 llvm::FunctionType* func_type = getFunctionType(cUnit);
1996
1997 if (func_type == NULL) {
1998 return false;
1999 }
2000
2001 cUnit->func = llvm::Function::Create(func_type,
2002 llvm::Function::ExternalLinkage,
2003 func_name, cUnit->module);
2004
2005 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2006 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
2007
2008 arg_iter->setName("method");
2009 ++arg_iter;
2010
2011 int startSReg = cUnit->numRegs;
2012
2013 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
2014 arg_iter->setName(StringPrintf("v%i_0", startSReg));
2015 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
2016 }
2017
2018 return true;
2019}
2020
2021bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
2022{
2023 // Skip the exit block
buzbeed1643e42012-09-05 14:06:51 -07002024 if ((bb->blockType == kDead) ||(bb->blockType == kExitBlock)) {
buzbee2cfc6392012-05-07 14:51:40 -07002025 cUnit->idToBlockMap.Put(bb->id, NULL);
2026 } else {
2027 int offset = bb->startOffset;
2028 bool entryBlock = (bb->blockType == kEntryBlock);
2029 llvm::BasicBlock* llvmBB =
2030 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
buzbee8320f382012-09-11 16:29:42 -07002031 StringPrintf(kLabelFormat, bb->catchEntry ? kCatchBlock :
2032 kNormalBlock, offset, bb->id), cUnit->func);
buzbee2cfc6392012-05-07 14:51:40 -07002033 if (entryBlock) {
2034 cUnit->entryBB = llvmBB;
2035 cUnit->placeholderBB =
2036 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
2037 cUnit->func);
2038 }
2039 cUnit->idToBlockMap.Put(bb->id, llvmBB);
2040 }
2041 return false;
2042}
2043
2044
2045/*
2046 * Convert MIR to LLVM_IR
2047 * o For each ssa name, create LLVM named value. Type these
2048 * appropriately, and ignore high half of wide and double operands.
2049 * o For each MIR basic block, create an LLVM basic block.
2050 * o Iterate through the MIR a basic block at a time, setting arguments
2051 * to recovered ssa name.
2052 */
2053void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
2054{
2055 initIR(cUnit);
2056 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
2057
2058 // Create the function
2059 createFunction(cUnit);
2060
2061 // Create an LLVM basic block for each MIR block in dfs preorder
2062 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
2063 kPreOrderDFSTraversal, false /* isIterative */);
2064 /*
2065 * Create an llvm named value for each MIR SSA name. Note: we'll use
2066 * placeholders for all non-argument values (because we haven't seen
2067 * the definition yet).
2068 */
2069 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2070 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2071 arg_iter++; /* Skip path method */
2072 for (int i = 0; i < cUnit->numSSARegs; i++) {
2073 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07002074 RegLocation rlTemp = cUnit->regLocation[i];
2075 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07002076 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
2077 } else if ((i < cUnit->numRegs) ||
2078 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07002079 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
2080 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07002081 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
2082 val->setName(llvmSSAName(cUnit, i));
buzbeecbd6d442012-11-17 14:11:25 -08002083 oatInsertGrowableList(cUnit, &cUnit->llvmValues, reinterpret_cast<uintptr_t>(val));
buzbee2cfc6392012-05-07 14:51:40 -07002084 } else {
2085 // Recover previously-created argument values
2086 llvm::Value* argVal = arg_iter++;
buzbeecbd6d442012-11-17 14:11:25 -08002087 oatInsertGrowableList(cUnit, &cUnit->llvmValues, reinterpret_cast<uintptr_t>(argVal));
buzbee2cfc6392012-05-07 14:51:40 -07002088 }
2089 }
buzbee2cfc6392012-05-07 14:51:40 -07002090
2091 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
2092 kPreOrderDFSTraversal, false /* Iterative */);
2093
buzbee4be777b2012-07-12 14:38:18 -07002094 /*
2095 * In a few rare cases of verification failure, the verifier will
2096 * replace one or more Dalvik opcodes with the special
2097 * throw-verification-failure opcode. This can leave the SSA graph
2098 * in an invalid state, as definitions may be lost, while uses retained.
2099 * To work around this problem, we insert placeholder definitions for
2100 * all Dalvik SSA regs in the "placeholder" block. Here, after
2101 * bitcode conversion is complete, we examine those placeholder definitions
2102 * and delete any with no references (which normally is all of them).
2103 *
2104 * If any definitions remain, we link the placeholder block into the
2105 * CFG. Otherwise, it is deleted.
2106 */
2107 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
2108 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
2109 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2110 DCHECK(inst != NULL);
2111 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2112 DCHECK(val != NULL);
2113 if (val->getNumUses() == 0) {
2114 inst->eraseFromParent();
2115 }
2116 }
2117 setDexOffset(cUnit, 0);
2118 if (cUnit->placeholderBB->empty()) {
2119 cUnit->placeholderBB->eraseFromParent();
2120 } else {
2121 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2122 cUnit->irb->CreateBr(cUnit->entryTargetBB);
2123 cUnit->entryTargetBB = cUnit->placeholderBB;
2124 }
2125 cUnit->irb->SetInsertPoint(cUnit->entryBB);
2126 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07002127
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002128 if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
2129 if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
2130 LOG(INFO) << "Bitcode verification FAILED for "
2131 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
2132 << " of size " << cUnit->insnsSize;
2133 cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
2134 }
2135 }
buzbee2cfc6392012-05-07 14:51:40 -07002136
buzbeead8f15e2012-06-18 14:49:45 -07002137 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
2138 // Write bitcode to file
2139 std::string errmsg;
2140 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
2141 oatReplaceSpecialChars(fname);
buzbee6459e7c2012-10-02 14:42:41 -07002142 // TODO: make configurable change naming mechanism to avoid fname length issues.
buzbee4f1181f2012-06-22 13:52:12 -07002143 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002144
buzbee6459e7c2012-10-02 14:42:41 -07002145 if (fname.size() > 240) {
2146 LOG(INFO) << "Warning: bitcode filename too long. Truncated.";
2147 fname.resize(240);
2148 }
2149
buzbeead8f15e2012-06-18 14:49:45 -07002150 llvm::OwningPtr<llvm::tool_output_file> out_file(
2151 new llvm::tool_output_file(fname.c_str(), errmsg,
2152 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002153
buzbeead8f15e2012-06-18 14:49:45 -07002154 if (!errmsg.empty()) {
2155 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2156 }
2157
2158 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2159 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002160 }
buzbee2cfc6392012-05-07 14:51:40 -07002161}
2162
2163RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2164 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002165 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002166 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2167 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002168 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002169 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002170 // FIXME: need to be more robust, handle FP and be in a position to
2171 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002172 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2173 memset(&res, 0, sizeof(res));
2174 res.location = kLocPhysReg;
2175 res.lowReg = oatAllocTemp(cUnit);
2176 res.home = true;
2177 res.sRegLow = INVALID_SREG;
2178 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002179 llvm::Type* ty = val->getType();
2180 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2181 (ty == cUnit->irb->getDoubleTy()));
2182 if (res.wide) {
2183 res.highReg = oatAllocTemp(cUnit);
2184 }
buzbee4f1181f2012-06-22 13:52:12 -07002185 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002186 } else {
2187 DCHECK_EQ(valName[0], 'v');
2188 int baseSReg = INVALID_SREG;
2189 sscanf(valName.c_str(), "v%d_", &baseSReg);
2190 res = cUnit->regLocation[baseSReg];
2191 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002192 }
2193 } else {
2194 res = it->second;
2195 }
2196 return res;
2197}
2198
2199Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2200{
2201 Instruction::Code res = Instruction::NOP;
2202 if (isWide) {
2203 switch(op) {
2204 case kOpAdd: res = Instruction::ADD_LONG; break;
2205 case kOpSub: res = Instruction::SUB_LONG; break;
2206 case kOpMul: res = Instruction::MUL_LONG; break;
2207 case kOpDiv: res = Instruction::DIV_LONG; break;
2208 case kOpRem: res = Instruction::REM_LONG; break;
2209 case kOpAnd: res = Instruction::AND_LONG; break;
2210 case kOpOr: res = Instruction::OR_LONG; break;
2211 case kOpXor: res = Instruction::XOR_LONG; break;
2212 case kOpLsl: res = Instruction::SHL_LONG; break;
2213 case kOpLsr: res = Instruction::USHR_LONG; break;
2214 case kOpAsr: res = Instruction::SHR_LONG; break;
2215 default: LOG(FATAL) << "Unexpected OpKind " << op;
2216 }
2217 } else if (isConst){
2218 switch(op) {
2219 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2220 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2221 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2222 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2223 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2224 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2225 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2226 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2227 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2228 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2229 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2230 default: LOG(FATAL) << "Unexpected OpKind " << op;
2231 }
2232 } else {
2233 switch(op) {
2234 case kOpAdd: res = Instruction::ADD_INT; break;
2235 case kOpSub: res = Instruction::SUB_INT; break;
2236 case kOpMul: res = Instruction::MUL_INT; break;
2237 case kOpDiv: res = Instruction::DIV_INT; break;
2238 case kOpRem: res = Instruction::REM_INT; break;
2239 case kOpAnd: res = Instruction::AND_INT; break;
2240 case kOpOr: res = Instruction::OR_INT; break;
2241 case kOpXor: res = Instruction::XOR_INT; break;
2242 case kOpLsl: res = Instruction::SHL_INT; break;
2243 case kOpLsr: res = Instruction::USHR_INT; break;
2244 case kOpAsr: res = Instruction::SHR_INT; break;
2245 default: LOG(FATAL) << "Unexpected OpKind " << op;
2246 }
2247 }
2248 return res;
2249}
2250
buzbee4f1181f2012-06-22 13:52:12 -07002251Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2252{
2253 Instruction::Code res = Instruction::NOP;
2254 if (isWide) {
2255 switch(op) {
2256 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2257 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2258 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2259 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2260 case kOpRem: res = Instruction::REM_DOUBLE; break;
2261 default: LOG(FATAL) << "Unexpected OpKind " << op;
2262 }
2263 } else {
2264 switch(op) {
2265 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2266 case kOpSub: res = Instruction::SUB_FLOAT; break;
2267 case kOpMul: res = Instruction::MUL_FLOAT; break;
2268 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2269 case kOpRem: res = Instruction::REM_FLOAT; break;
2270 default: LOG(FATAL) << "Unexpected OpKind " << op;
2271 }
2272 }
2273 return res;
2274}
2275
2276void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2277{
2278 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002279 /*
2280 * Normally, we won't ever generate an FP operation with an immediate
2281 * operand (not supported in Dex instruction set). However, the IR builder
2282 * may insert them - in particular for createNegFP. Recognize this case
2283 * and deal with it.
2284 */
2285 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2286 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2287 DCHECK(op2C == NULL);
2288 if ((op1C != NULL) && (op == kOpSub)) {
2289 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2290 if (rlDest.wide) {
2291 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2292 } else {
2293 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2294 }
buzbee4f1181f2012-06-22 13:52:12 -07002295 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002296 DCHECK(op1C == NULL);
2297 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2298 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2299 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2300 if (rlDest.wide) {
2301 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2302 } else {
2303 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2304 }
buzbee4f1181f2012-06-22 13:52:12 -07002305 }
2306}
2307
buzbee101305f2012-06-28 18:00:56 -07002308void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2309 Instruction::Code opcode)
2310{
2311 RegLocation rlDest = getLoc(cUnit, inst);
2312 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2313 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2314}
2315
buzbee76592632012-06-29 15:18:35 -07002316void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2317{
2318 RegLocation rlDest = getLoc(cUnit, inst);
2319 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2320 Instruction::Code opcode;
2321 if (rlDest.wide) {
2322 if (rlSrc.wide) {
2323 opcode = Instruction::LONG_TO_DOUBLE;
2324 } else {
2325 opcode = Instruction::INT_TO_DOUBLE;
2326 }
2327 } else {
2328 if (rlSrc.wide) {
2329 opcode = Instruction::LONG_TO_FLOAT;
2330 } else {
2331 opcode = Instruction::INT_TO_FLOAT;
2332 }
2333 }
2334 genConversion(cUnit, opcode, rlDest, rlSrc);
2335}
2336
TDYa1274ec8ccd2012-08-11 07:04:57 -07002337void cvtFPToInt(CompilationUnit* cUnit, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002338{
TDYa1274ec8ccd2012-08-11 07:04:57 -07002339 RegLocation rlDest = getLoc(cUnit, call_inst);
2340 RegLocation rlSrc = getLoc(cUnit, call_inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002341 Instruction::Code opcode;
2342 if (rlDest.wide) {
2343 if (rlSrc.wide) {
2344 opcode = Instruction::DOUBLE_TO_LONG;
2345 } else {
2346 opcode = Instruction::FLOAT_TO_LONG;
2347 }
2348 } else {
2349 if (rlSrc.wide) {
2350 opcode = Instruction::DOUBLE_TO_INT;
2351 } else {
2352 opcode = Instruction::FLOAT_TO_INT;
2353 }
2354 }
2355 genConversion(cUnit, opcode, rlDest, rlSrc);
2356}
2357
2358void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2359{
2360 RegLocation rlDest = getLoc(cUnit, inst);
2361 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2362 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2363}
2364
2365void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2366{
2367 RegLocation rlDest = getLoc(cUnit, inst);
2368 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2369 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2370 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2371 storeValue(cUnit, rlDest, rlSrc);
2372}
2373
2374void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2375{
2376 RegLocation rlDest = getLoc(cUnit, inst);
2377 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2378 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2379}
2380
2381
buzbee101305f2012-06-28 18:00:56 -07002382void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2383{
2384 // TODO: evaluate src/tgt types and add general support for more than int to long
2385 RegLocation rlDest = getLoc(cUnit, inst);
2386 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2387 DCHECK(rlDest.wide);
2388 DCHECK(!rlSrc.wide);
2389 DCHECK(!rlDest.fp);
2390 DCHECK(!rlSrc.fp);
2391 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2392 if (rlSrc.location == kLocPhysReg) {
2393 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2394 } else {
2395 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2396 }
2397 if (isSigned) {
2398 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2399 } else {
2400 loadConstant(cUnit, rlResult.highReg, 0);
2401 }
2402 storeValueWide(cUnit, rlDest, rlResult);
2403}
2404
buzbee2cfc6392012-05-07 14:51:40 -07002405void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2406{
2407 RegLocation rlDest = getLoc(cUnit, inst);
2408 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002409 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002410 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2411 if ((op == kOpSub) && (lhsImm != NULL)) {
2412 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002413 if (rlSrc1.wide) {
2414 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2415 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2416 } else {
2417 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2418 lhsImm->getSExtValue());
2419 }
buzbee4f1181f2012-06-22 13:52:12 -07002420 return;
2421 }
2422 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002423 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2424 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002425 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2426 if (!rlDest.wide && (constRhs != NULL)) {
buzbee2cfc6392012-05-07 14:51:40 -07002427 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
buzbee9a2487f2012-07-26 14:01:13 -07002428 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002429 } else {
2430 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002431 RegLocation rlSrc2;
2432 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002433 // ir_builder converts NOT_LONG to xor src, -1. Restore
2434 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2435 DCHECK_EQ(-1L, constRhs->getSExtValue());
2436 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002437 rlSrc2 = rlSrc1;
2438 } else {
2439 rlSrc2 = getLoc(cUnit, rhs);
2440 }
buzbee2cfc6392012-05-07 14:51:40 -07002441 if (rlDest.wide) {
2442 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2443 } else {
2444 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2445 }
2446 }
2447}
2448
buzbee2a83e8f2012-07-13 16:42:30 -07002449void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2450 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002451{
buzbee2a83e8f2012-07-13 16:42:30 -07002452 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2453 RegLocation rlDest = getLoc(cUnit, callInst);
2454 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2455 llvm::Value* rhs = callInst->getArgOperand(1);
2456 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2457 DCHECK(!rlDest.wide);
2458 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002459 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002460 RegLocation rlShift = getLoc(cUnit, rhs);
2461 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2462 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2463 } else {
2464 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2465 }
buzbee101305f2012-06-28 18:00:56 -07002466 }
2467}
2468
buzbee2cfc6392012-05-07 14:51:40 -07002469void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2470{
2471 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2472 DCHECK(brInst != NULL);
2473 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2474 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2475 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2476}
2477
2478void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2479{
2480 // Nop - these have already been processed
2481}
2482
2483void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2484{
2485 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2486 llvm::Value* retVal = retInst->getReturnValue();
2487 if (retVal != NULL) {
2488 RegLocation rlSrc = getLoc(cUnit, retVal);
2489 if (rlSrc.wide) {
2490 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2491 } else {
2492 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2493 }
2494 }
2495 genExitSequence(cUnit);
2496}
2497
2498ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2499{
2500 ConditionCode res = kCondAl;
2501 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002502 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002503 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2504 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2505 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002506 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002507 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002508 default: LOG(FATAL) << "Unexpected llvm condition";
2509 }
2510 return res;
2511}
2512
2513void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2514{
2515 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2516 UNIMPLEMENTED(FATAL);
2517}
2518
2519void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2520 llvm::BranchInst* brInst)
2521{
2522 // Get targets
2523 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2524 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2525 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2526 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2527 // Get comparison operands
2528 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2529 ConditionCode cond = getCond(iCmpInst->getPredicate());
2530 llvm::Value* lhs = iCmpInst->getOperand(0);
2531 // Not expecting a constant as 1st operand
2532 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2533 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2534 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2535 llvm::Value* rhs = inst->getOperand(1);
buzbeeb046e162012-10-30 15:48:42 -07002536 if (cUnit->instructionSet == kMips) {
2537 // Compare and branch in one shot
2538 UNIMPLEMENTED(FATAL);
2539 }
buzbee2cfc6392012-05-07 14:51:40 -07002540 //Compare, then branch
2541 // TODO: handle fused CMP_LONG/IF_xxZ case
2542 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2543 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002544 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2545 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002546 } else {
2547 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2548 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2549 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2550 }
2551 opCondBranch(cUnit, cond, taken);
buzbee2cfc6392012-05-07 14:51:40 -07002552 // Fallthrough
2553 opUnconditionalBranch(cUnit, fallThrough);
2554}
2555
2556void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2557 llvm::Function* callee)
2558{
2559 UNIMPLEMENTED(FATAL);
2560}
2561
buzbee2cfc6392012-05-07 14:51:40 -07002562void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2563{
buzbee4f1181f2012-06-22 13:52:12 -07002564 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002565 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2566 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002567 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2568 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002569 if (rlSrc.wide) {
2570 storeValueWide(cUnit, rlDest, rlSrc);
2571 } else {
2572 storeValue(cUnit, rlDest, rlSrc);
2573 }
2574}
2575
2576// Note: Immediate arg is a ConstantInt regardless of result type
2577void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2578{
buzbee4f1181f2012-06-22 13:52:12 -07002579 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002580 llvm::ConstantInt* src =
2581 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2582 uint64_t immval = src->getZExtValue();
2583 RegLocation rlDest = getLoc(cUnit, callInst);
2584 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2585 if (rlDest.wide) {
2586 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2587 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2588 storeValueWide(cUnit, rlDest, rlResult);
2589 } else {
2590 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2591 storeValue(cUnit, rlDest, rlResult);
2592 }
2593}
2594
buzbee101305f2012-06-28 18:00:56 -07002595void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2596 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002597{
buzbee4f1181f2012-06-22 13:52:12 -07002598 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002599 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002600 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002601 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002602 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002603 if (isString) {
2604 genConstString(cUnit, index, rlDest);
2605 } else {
2606 genConstClass(cUnit, index, rlDest);
2607 }
2608}
2609
2610void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2611{
2612 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2613 llvm::ConstantInt* offsetVal =
2614 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2615 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2616 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002617}
2618
buzbee4f1181f2012-06-22 13:52:12 -07002619void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2620{
buzbee32412962012-06-26 16:27:56 -07002621 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002622 llvm::ConstantInt* typeIdxVal =
2623 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2624 uint32_t typeIdx = typeIdxVal->getZExtValue();
2625 RegLocation rlDest = getLoc(cUnit, callInst);
2626 genNewInstance(cUnit, typeIdx, rlDest);
2627}
2628
buzbee8fa0fda2012-06-27 15:44:52 -07002629void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2630{
2631 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2632 llvm::ConstantInt* typeIdxVal =
2633 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2634 uint32_t typeIdx = typeIdxVal->getZExtValue();
2635 llvm::Value* len = callInst->getArgOperand(1);
2636 RegLocation rlLen = getLoc(cUnit, len);
2637 RegLocation rlDest = getLoc(cUnit, callInst);
2638 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2639}
2640
2641void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2642{
2643 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2644 llvm::ConstantInt* typeIdxVal =
2645 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2646 uint32_t typeIdx = typeIdxVal->getZExtValue();
2647 llvm::Value* src = callInst->getArgOperand(1);
2648 RegLocation rlSrc = getLoc(cUnit, src);
2649 RegLocation rlDest = getLoc(cUnit, callInst);
2650 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2651}
2652
buzbee32412962012-06-26 16:27:56 -07002653void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2654{
2655 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2656 llvm::Value* src = callInst->getArgOperand(0);
2657 RegLocation rlSrc = getLoc(cUnit, src);
2658 genThrow(cUnit, rlSrc);
2659}
2660
buzbee8fa0fda2012-06-27 15:44:52 -07002661void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2662 llvm::CallInst* callInst)
2663{
2664 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2665 llvm::ConstantInt* optFlags =
2666 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2667 llvm::Value* src = callInst->getArgOperand(1);
2668 RegLocation rlSrc = getLoc(cUnit, src);
2669 if (isEnter) {
2670 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2671 } else {
2672 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2673 }
2674}
2675
buzbee76592632012-06-29 15:18:35 -07002676void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002677{
2678 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2679 llvm::ConstantInt* optFlags =
2680 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2681 llvm::Value* src = callInst->getArgOperand(1);
2682 RegLocation rlSrc = getLoc(cUnit, src);
2683 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2684 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2685 RegLocation rlDest = getLoc(cUnit, callInst);
2686 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2687 int lenOffset = Array::LengthOffset().Int32Value();
2688 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2689 storeValue(cUnit, rlDest, rlResult);
2690}
2691
buzbee32412962012-06-26 16:27:56 -07002692void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2693{
buzbee32412962012-06-26 16:27:56 -07002694 RegLocation rlDest = getLoc(cUnit, callInst);
Ian Rogers474b6da2012-09-25 00:20:38 -07002695 genMoveException(cUnit, rlDest);
buzbee32412962012-06-26 16:27:56 -07002696}
2697
buzbee4f1181f2012-06-22 13:52:12 -07002698void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2699 bool isObject)
2700{
buzbee32412962012-06-26 16:27:56 -07002701 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002702 llvm::ConstantInt* typeIdxVal =
2703 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2704 uint32_t typeIdx = typeIdxVal->getZExtValue();
2705 RegLocation rlDest = getLoc(cUnit, callInst);
2706 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2707}
2708
buzbee8fa0fda2012-06-27 15:44:52 -07002709void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2710 bool isObject)
2711{
2712 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2713 llvm::ConstantInt* typeIdxVal =
2714 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2715 uint32_t typeIdx = typeIdxVal->getZExtValue();
2716 llvm::Value* src = callInst->getArgOperand(1);
2717 RegLocation rlSrc = getLoc(cUnit, src);
2718 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2719}
2720
2721void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2722 int scale)
2723{
2724 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2725 llvm::ConstantInt* optFlags =
2726 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2727 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2728 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2729 RegLocation rlDest = getLoc(cUnit, callInst);
2730 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2731 rlDest, scale);
2732}
2733
2734void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002735 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002736{
2737 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2738 llvm::ConstantInt* optFlags =
2739 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2740 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2741 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2742 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002743 if (isObject) {
2744 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2745 rlSrc, scale);
2746 } else {
2747 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2748 rlSrc, scale);
2749 }
2750}
2751
2752void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2753{
2754 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2755}
2756
2757void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2758 OpSize size, int scale)
2759{
2760 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002761}
2762
buzbee101305f2012-06-28 18:00:56 -07002763void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2764 bool isWide, bool isObj)
2765{
2766 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2767 llvm::ConstantInt* optFlags =
2768 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2769 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2770 llvm::ConstantInt* fieldIdx =
2771 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2772 RegLocation rlDest = getLoc(cUnit, callInst);
2773 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2774 size, rlDest, rlObj, isWide, isObj);
2775}
2776
2777void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2778 bool isWide, bool isObj)
2779{
2780 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2781 llvm::ConstantInt* optFlags =
2782 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2783 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2784 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2785 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002786 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002787 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2788 size, rlSrc, rlObj, isWide, isObj);
2789}
2790
2791void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2792{
2793 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2794 llvm::ConstantInt* typeIdx =
2795 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2796 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2797 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2798}
2799
buzbee76592632012-06-29 15:18:35 -07002800void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2801 Instruction::Code opcode)
2802{
2803 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2804 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2805 RegLocation rlDest = getLoc(cUnit, callInst);
2806 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2807}
2808
2809void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2810{
2811 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2812 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2813 RegLocation rlDest = getLoc(cUnit, callInst);
2814 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2815}
2816
buzbeef58c12c2012-07-03 15:06:29 -07002817void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2818{
2819 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2820 DCHECK(swInst != NULL);
2821 llvm::Value* testVal = swInst->getCondition();
2822 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2823 DCHECK(tableOffsetNode != NULL);
2824 llvm::ConstantInt* tableOffsetValue =
2825 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2826 int32_t tableOffset = tableOffsetValue->getSExtValue();
2827 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeeeaf09bc2012-11-15 14:51:41 -08002828 const uint16_t* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2829 uint16_t tableMagic = *table;
buzbeea1da8a52012-07-09 14:00:21 -07002830 if (tableMagic == 0x100) {
2831 genPackedSwitch(cUnit, tableOffset, rlSrc);
2832 } else {
2833 DCHECK_EQ(tableMagic, 0x200);
2834 genSparseSwitch(cUnit, tableOffset, rlSrc);
2835 }
buzbeef58c12c2012-07-03 15:06:29 -07002836}
2837
buzbee6969d502012-06-15 16:40:31 -07002838void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002839 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002840{
buzbeecbd6d442012-11-17 14:11:25 -08002841 CallInfo* info = static_cast<CallInfo*>(oatNew(cUnit, sizeof(CallInfo), true, kAllocMisc));
buzbee8fa0fda2012-06-27 15:44:52 -07002842 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002843 info->result.location = kLocInvalid;
2844 } else {
2845 info->result = getLoc(cUnit, callInst);
2846 }
2847 llvm::ConstantInt* invokeTypeVal =
2848 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2849 llvm::ConstantInt* methodIndexVal =
2850 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2851 llvm::ConstantInt* optFlagsVal =
2852 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2853 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2854 info->index = methodIndexVal->getZExtValue();
2855 info->optFlags = optFlagsVal->getZExtValue();
2856 info->offset = cUnit->currentDalvikOffset;
2857
buzbee6969d502012-06-15 16:40:31 -07002858 // Count the argument words, and then build argument array.
2859 info->numArgWords = 0;
2860 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2861 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2862 info->numArgWords += tLoc.wide ? 2 : 1;
2863 }
buzbeecbd6d442012-11-17 14:11:25 -08002864 info->args = (info->numArgWords == 0) ? NULL : static_cast<RegLocation*>
2865 (oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc));
buzbee6969d502012-06-15 16:40:31 -07002866 // Now, fill in the location records, synthesizing high loc of wide vals
2867 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002868 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002869 if (info->args[next].wide) {
2870 next++;
2871 // TODO: Might make sense to mark this as an invalid loc
2872 info->args[next].origSReg = info->args[next-1].origSReg+1;
2873 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2874 }
2875 next++;
2876 }
buzbee4f4dfc72012-07-02 14:54:44 -07002877 // TODO - rework such that we no longer need isRange
2878 info->isRange = (info->numArgWords > 5);
2879
buzbee76592632012-06-29 15:18:35 -07002880 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002881 genFilledNewArray(cUnit, info);
2882 } else {
2883 genInvoke(cUnit, info);
2884 }
buzbee6969d502012-06-15 16:40:31 -07002885}
2886
buzbeead8f15e2012-06-18 14:49:45 -07002887/* Look up the RegLocation associated with a Value. Must already be defined */
2888RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2889{
2890 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2891 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2892 return it->second;
2893}
2894
buzbee2cfc6392012-05-07 14:51:40 -07002895bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2896{
buzbee0967a252012-09-14 10:43:54 -07002897 while (cUnit->llvmBlocks.find(bb) == cUnit->llvmBlocks.end()) {
2898 llvm::BasicBlock* nextBB = NULL;
2899 cUnit->llvmBlocks.insert(bb);
2900 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2901 // Define the starting label
2902 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2903 // Extract the type and starting offset from the block's name
buzbee951c0a12012-10-03 16:31:39 -07002904 char blockType = kInvalidBlock;
2905 if (isEntry) {
2906 blockType = kNormalBlock;
2907 blockLabel->operands[0] = 0;
2908 } else if (!bb->hasName()) {
2909 blockType = kNormalBlock;
2910 blockLabel->operands[0] = DexFile::kDexNoIndex;
buzbee0967a252012-09-14 10:43:54 -07002911 } else {
buzbee951c0a12012-10-03 16:31:39 -07002912 std::string blockName = bb->getName().str();
2913 int dummy;
2914 sscanf(blockName.c_str(), kLabelFormat, &blockType, &blockLabel->operands[0], &dummy);
2915 cUnit->currentDalvikOffset = blockLabel->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002916 }
buzbee951c0a12012-10-03 16:31:39 -07002917 DCHECK((blockType == kNormalBlock) || (blockType == kCatchBlock));
2918 cUnit->currentDalvikOffset = blockLabel->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002919 // Set the label kind
2920 blockLabel->opcode = kPseudoNormalBlockLabel;
2921 // Insert the label
2922 oatAppendLIR(cUnit, blockLabel);
buzbee2cfc6392012-05-07 14:51:40 -07002923
buzbee0967a252012-09-14 10:43:54 -07002924 LIR* headLIR = NULL;
buzbee8320f382012-09-11 16:29:42 -07002925
buzbee0967a252012-09-14 10:43:54 -07002926 if (blockType == kCatchBlock) {
Bill Buzbeea5b30242012-09-28 07:19:44 -07002927 headLIR = newLIR0(cUnit, kPseudoExportedPC);
buzbee0967a252012-09-14 10:43:54 -07002928 }
buzbee8320f382012-09-11 16:29:42 -07002929
buzbee0967a252012-09-14 10:43:54 -07002930 // Free temp registers and reset redundant store tracking */
2931 oatResetRegPool(cUnit);
2932 oatResetDefTracking(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002933
buzbee0967a252012-09-14 10:43:54 -07002934 //TODO: restore oat incoming liveness optimization
2935 oatClobberAllRegs(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002936
buzbee0967a252012-09-14 10:43:54 -07002937 if (isEntry) {
buzbeecbd6d442012-11-17 14:11:25 -08002938 RegLocation* argLocs = static_cast<RegLocation*>
2939 (oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc));
buzbee0967a252012-09-14 10:43:54 -07002940 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2941 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2942 // Skip past Method*
2943 it++;
2944 for (unsigned i = 0; it != it_end; ++it) {
2945 llvm::Value* val = it;
2946 argLocs[i++] = valToLoc(cUnit, val);
2947 llvm::Type* ty = val->getType();
2948 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2949 argLocs[i] = argLocs[i-1];
2950 argLocs[i].lowReg = argLocs[i].highReg;
2951 argLocs[i].origSReg++;
2952 argLocs[i].sRegLow = INVALID_SREG;
2953 argLocs[i].highWord = true;
2954 i++;
2955 }
2956 }
2957 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
2958 }
2959
2960 // Visit all of the instructions in the block
2961 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2962 llvm::Instruction* inst = it;
2963 llvm::BasicBlock::iterator nextIt = ++it;
2964 // Extract the Dalvik offset from the instruction
2965 uint32_t opcode = inst->getOpcode();
2966 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2967 if (dexOffsetNode != NULL) {
2968 llvm::ConstantInt* dexOffsetValue =
2969 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2970 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2971 }
2972
2973 oatResetRegPool(cUnit);
2974 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2975 oatClobberAllRegs(cUnit);
2976 }
2977
2978 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2979 oatResetDefTracking(cUnit);
2980 }
2981
2982 #ifndef NDEBUG
2983 /* Reset temp tracking sanity check */
2984 cUnit->liveSReg = INVALID_SREG;
2985 #endif
2986
2987 // TODO: use llvm opcode name here instead of "boundary" if verbose
2988 LIR* boundaryLIR = markBoundary(cUnit, cUnit->currentDalvikOffset, "boundary");
2989
2990 /* Remember the first LIR for thisl block*/
2991 if (headLIR == NULL) {
2992 headLIR = boundaryLIR;
2993 headLIR->defMask = ENCODE_ALL;
2994 }
2995
2996 switch(opcode) {
2997
2998 case llvm::Instruction::ICmp: {
2999 llvm::Instruction* nextInst = nextIt;
3000 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
3001 if (brInst != NULL /* and... */) {
3002 cvtICmpBr(cUnit, inst, brInst);
3003 ++it;
3004 } else {
3005 cvtICmp(cUnit, inst);
3006 }
3007 }
3008 break;
3009
3010 case llvm::Instruction::Call: {
3011 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
3012 llvm::Function* callee = callInst->getCalledFunction();
3013 greenland::IntrinsicHelper::IntrinsicId id =
3014 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3015 switch (id) {
3016 case greenland::IntrinsicHelper::AllocaShadowFrame:
3017 case greenland::IntrinsicHelper::SetShadowFrameEntry:
3018 case greenland::IntrinsicHelper::PopShadowFrame:
TDYa1278e950c12012-11-02 09:58:19 -07003019 case greenland::IntrinsicHelper::SetVReg:
buzbee0967a252012-09-14 10:43:54 -07003020 // Ignore shadow frame stuff for quick compiler
3021 break;
3022 case greenland::IntrinsicHelper::CopyInt:
3023 case greenland::IntrinsicHelper::CopyObj:
3024 case greenland::IntrinsicHelper::CopyFloat:
3025 case greenland::IntrinsicHelper::CopyLong:
3026 case greenland::IntrinsicHelper::CopyDouble:
3027 cvtCopy(cUnit, callInst);
3028 break;
3029 case greenland::IntrinsicHelper::ConstInt:
3030 case greenland::IntrinsicHelper::ConstObj:
3031 case greenland::IntrinsicHelper::ConstLong:
3032 case greenland::IntrinsicHelper::ConstFloat:
3033 case greenland::IntrinsicHelper::ConstDouble:
3034 cvtConst(cUnit, callInst);
3035 break;
3036 case greenland::IntrinsicHelper::DivInt:
3037 case greenland::IntrinsicHelper::DivLong:
3038 cvtBinOp(cUnit, kOpDiv, inst);
3039 break;
3040 case greenland::IntrinsicHelper::RemInt:
3041 case greenland::IntrinsicHelper::RemLong:
3042 cvtBinOp(cUnit, kOpRem, inst);
3043 break;
3044 case greenland::IntrinsicHelper::MethodInfo:
3045 // Already dealt with - just ignore it here.
3046 break;
3047 case greenland::IntrinsicHelper::CheckSuspend:
3048 genSuspendTest(cUnit, 0 /* optFlags already applied */);
3049 break;
3050 case greenland::IntrinsicHelper::HLInvokeObj:
3051 case greenland::IntrinsicHelper::HLInvokeFloat:
3052 case greenland::IntrinsicHelper::HLInvokeDouble:
3053 case greenland::IntrinsicHelper::HLInvokeLong:
3054 case greenland::IntrinsicHelper::HLInvokeInt:
3055 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
3056 break;
3057 case greenland::IntrinsicHelper::HLInvokeVoid:
3058 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
3059 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003060 case greenland::IntrinsicHelper::HLFilledNewArray:
buzbee0967a252012-09-14 10:43:54 -07003061 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
3062 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003063 case greenland::IntrinsicHelper::HLFillArrayData:
buzbee0967a252012-09-14 10:43:54 -07003064 cvtFillArrayData(cUnit, callInst);
3065 break;
3066 case greenland::IntrinsicHelper::ConstString:
3067 cvtConstObject(cUnit, callInst, true /* isString */);
3068 break;
3069 case greenland::IntrinsicHelper::ConstClass:
3070 cvtConstObject(cUnit, callInst, false /* isString */);
3071 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003072 case greenland::IntrinsicHelper::HLCheckCast:
buzbee0967a252012-09-14 10:43:54 -07003073 cvtCheckCast(cUnit, callInst);
3074 break;
3075 case greenland::IntrinsicHelper::NewInstance:
3076 cvtNewInstance(cUnit, callInst);
3077 break;
3078 case greenland::IntrinsicHelper::HLSgetObject:
3079 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
3080 break;
3081 case greenland::IntrinsicHelper::HLSget:
3082 case greenland::IntrinsicHelper::HLSgetFloat:
3083 case greenland::IntrinsicHelper::HLSgetBoolean:
3084 case greenland::IntrinsicHelper::HLSgetByte:
3085 case greenland::IntrinsicHelper::HLSgetChar:
3086 case greenland::IntrinsicHelper::HLSgetShort:
3087 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
3088 break;
3089 case greenland::IntrinsicHelper::HLSgetWide:
3090 case greenland::IntrinsicHelper::HLSgetDouble:
3091 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
3092 break;
3093 case greenland::IntrinsicHelper::HLSput:
3094 case greenland::IntrinsicHelper::HLSputFloat:
3095 case greenland::IntrinsicHelper::HLSputBoolean:
3096 case greenland::IntrinsicHelper::HLSputByte:
3097 case greenland::IntrinsicHelper::HLSputChar:
3098 case greenland::IntrinsicHelper::HLSputShort:
3099 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
3100 break;
3101 case greenland::IntrinsicHelper::HLSputWide:
3102 case greenland::IntrinsicHelper::HLSputDouble:
3103 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
3104 break;
3105 case greenland::IntrinsicHelper::HLSputObject:
3106 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
3107 break;
3108 case greenland::IntrinsicHelper::GetException:
3109 cvtMoveException(cUnit, callInst);
3110 break;
TDYa127f71bf5a2012-07-29 20:09:52 -07003111 case greenland::IntrinsicHelper::HLThrowException:
buzbee0967a252012-09-14 10:43:54 -07003112 cvtThrow(cUnit, callInst);
3113 break;
3114 case greenland::IntrinsicHelper::MonitorEnter:
3115 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
3116 break;
3117 case greenland::IntrinsicHelper::MonitorExit:
3118 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
3119 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003120 case greenland::IntrinsicHelper::OptArrayLength:
buzbee0967a252012-09-14 10:43:54 -07003121 cvtArrayLength(cUnit, callInst);
3122 break;
3123 case greenland::IntrinsicHelper::NewArray:
3124 cvtNewArray(cUnit, callInst);
3125 break;
3126 case greenland::IntrinsicHelper::InstanceOf:
3127 cvtInstanceOf(cUnit, callInst);
3128 break;
3129
3130 case greenland::IntrinsicHelper::HLArrayGet:
3131 case greenland::IntrinsicHelper::HLArrayGetObject:
3132 case greenland::IntrinsicHelper::HLArrayGetFloat:
3133 cvtAget(cUnit, callInst, kWord, 2);
3134 break;
3135 case greenland::IntrinsicHelper::HLArrayGetWide:
3136 case greenland::IntrinsicHelper::HLArrayGetDouble:
3137 cvtAget(cUnit, callInst, kLong, 3);
3138 break;
3139 case greenland::IntrinsicHelper::HLArrayGetBoolean:
3140 cvtAget(cUnit, callInst, kUnsignedByte, 0);
3141 break;
3142 case greenland::IntrinsicHelper::HLArrayGetByte:
3143 cvtAget(cUnit, callInst, kSignedByte, 0);
3144 break;
3145 case greenland::IntrinsicHelper::HLArrayGetChar:
3146 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
3147 break;
3148 case greenland::IntrinsicHelper::HLArrayGetShort:
3149 cvtAget(cUnit, callInst, kSignedHalf, 1);
3150 break;
3151
3152 case greenland::IntrinsicHelper::HLArrayPut:
3153 case greenland::IntrinsicHelper::HLArrayPutFloat:
3154 cvtAputPrimitive(cUnit, callInst, kWord, 2);
3155 break;
3156 case greenland::IntrinsicHelper::HLArrayPutObject:
3157 cvtAputObj(cUnit, callInst);
3158 break;
3159 case greenland::IntrinsicHelper::HLArrayPutWide:
3160 case greenland::IntrinsicHelper::HLArrayPutDouble:
3161 cvtAputPrimitive(cUnit, callInst, kLong, 3);
3162 break;
3163 case greenland::IntrinsicHelper::HLArrayPutBoolean:
3164 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
3165 break;
3166 case greenland::IntrinsicHelper::HLArrayPutByte:
3167 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
3168 break;
3169 case greenland::IntrinsicHelper::HLArrayPutChar:
3170 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
3171 break;
3172 case greenland::IntrinsicHelper::HLArrayPutShort:
3173 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
3174 break;
3175
3176 case greenland::IntrinsicHelper::HLIGet:
3177 case greenland::IntrinsicHelper::HLIGetFloat:
3178 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3179 break;
3180 case greenland::IntrinsicHelper::HLIGetObject:
3181 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3182 break;
3183 case greenland::IntrinsicHelper::HLIGetWide:
3184 case greenland::IntrinsicHelper::HLIGetDouble:
3185 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3186 break;
3187 case greenland::IntrinsicHelper::HLIGetBoolean:
3188 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3189 false /* obj */);
3190 break;
3191 case greenland::IntrinsicHelper::HLIGetByte:
3192 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3193 false /* obj */);
3194 break;
3195 case greenland::IntrinsicHelper::HLIGetChar:
3196 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3197 false /* obj */);
3198 break;
3199 case greenland::IntrinsicHelper::HLIGetShort:
3200 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3201 false /* obj */);
3202 break;
3203
3204 case greenland::IntrinsicHelper::HLIPut:
3205 case greenland::IntrinsicHelper::HLIPutFloat:
3206 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3207 break;
3208 case greenland::IntrinsicHelper::HLIPutObject:
3209 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3210 break;
3211 case greenland::IntrinsicHelper::HLIPutWide:
3212 case greenland::IntrinsicHelper::HLIPutDouble:
3213 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3214 break;
3215 case greenland::IntrinsicHelper::HLIPutBoolean:
3216 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3217 false /* obj */);
3218 break;
3219 case greenland::IntrinsicHelper::HLIPutByte:
3220 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3221 false /* obj */);
3222 break;
3223 case greenland::IntrinsicHelper::HLIPutChar:
3224 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3225 false /* obj */);
3226 break;
3227 case greenland::IntrinsicHelper::HLIPutShort:
3228 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3229 false /* obj */);
3230 break;
3231
3232 case greenland::IntrinsicHelper::IntToChar:
3233 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3234 break;
3235 case greenland::IntrinsicHelper::IntToShort:
3236 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3237 break;
3238 case greenland::IntrinsicHelper::IntToByte:
3239 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3240 break;
3241
TDYa1274ec8ccd2012-08-11 07:04:57 -07003242 case greenland::IntrinsicHelper::F2I:
3243 case greenland::IntrinsicHelper::D2I:
3244 case greenland::IntrinsicHelper::F2L:
3245 case greenland::IntrinsicHelper::D2L:
3246 cvtFPToInt(cUnit, callInst);
3247 break;
3248
buzbee0967a252012-09-14 10:43:54 -07003249 case greenland::IntrinsicHelper::CmplFloat:
3250 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3251 break;
3252 case greenland::IntrinsicHelper::CmpgFloat:
3253 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3254 break;
3255 case greenland::IntrinsicHelper::CmplDouble:
3256 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3257 break;
3258 case greenland::IntrinsicHelper::CmpgDouble:
3259 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3260 break;
3261
3262 case greenland::IntrinsicHelper::CmpLong:
3263 cvtLongCompare(cUnit, callInst);
3264 break;
3265
3266 case greenland::IntrinsicHelper::SHLLong:
3267 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
3268 break;
3269 case greenland::IntrinsicHelper::SHRLong:
3270 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3271 break;
3272 case greenland::IntrinsicHelper::USHRLong:
3273 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3274 break;
3275 case greenland::IntrinsicHelper::SHLInt:
3276 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3277 break;
3278 case greenland::IntrinsicHelper::SHRInt:
3279 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3280 break;
3281 case greenland::IntrinsicHelper::USHRInt:
3282 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3283 break;
3284
3285 case greenland::IntrinsicHelper::CatchTargets: {
3286 llvm::SwitchInst* swInst =
3287 llvm::dyn_cast<llvm::SwitchInst>(nextIt);
3288 DCHECK(swInst != NULL);
3289 /*
3290 * Discard the edges and the following conditional branch.
3291 * Do a direct branch to the default target (which is the
3292 * "work" portion of the pair.
3293 * TODO: awful code layout - rework
3294 */
3295 llvm::BasicBlock* targetBB = swInst->getDefaultDest();
3296 DCHECK(targetBB != NULL);
3297 opUnconditionalBranch(cUnit,
3298 cUnit->blockToLabelMap.Get(targetBB));
3299 ++it;
3300 // Set next bb to default target - improves code layout
3301 nextBB = targetBB;
3302 }
3303 break;
3304
3305 default:
buzbeecbd6d442012-11-17 14:11:25 -08003306 LOG(FATAL) << "Unexpected intrinsic " << cUnit->intrinsic_helper->GetName(id);
buzbee0967a252012-09-14 10:43:54 -07003307 }
3308 }
3309 break;
3310
3311 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3312 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3313 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3314 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3315 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3316 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3317 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3318 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3319 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
3320 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3321 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
3322 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3323 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3324 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3325 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3326 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
3327 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003328 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3329 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3330 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
3331
3332 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3333 break;
3334 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3335 break;
3336
3337 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3338
3339 case llvm::Instruction::Unreachable:
3340 break; // FIXME: can we really ignore these?
3341
3342 case llvm::Instruction::Shl:
3343 case llvm::Instruction::LShr:
3344 case llvm::Instruction::AShr:
3345 case llvm::Instruction::Invoke:
3346 case llvm::Instruction::FPToUI:
TDYa1274ec8ccd2012-08-11 07:04:57 -07003347 case llvm::Instruction::FPToSI:
buzbee0967a252012-09-14 10:43:54 -07003348 case llvm::Instruction::UIToFP:
3349 case llvm::Instruction::PtrToInt:
3350 case llvm::Instruction::IntToPtr:
3351 case llvm::Instruction::FCmp:
3352 case llvm::Instruction::URem:
3353 case llvm::Instruction::UDiv:
3354 case llvm::Instruction::Resume:
3355 case llvm::Instruction::Alloca:
3356 case llvm::Instruction::GetElementPtr:
3357 case llvm::Instruction::Fence:
3358 case llvm::Instruction::AtomicCmpXchg:
3359 case llvm::Instruction::AtomicRMW:
3360 case llvm::Instruction::BitCast:
3361 case llvm::Instruction::VAArg:
3362 case llvm::Instruction::Select:
3363 case llvm::Instruction::UserOp1:
3364 case llvm::Instruction::UserOp2:
3365 case llvm::Instruction::ExtractElement:
3366 case llvm::Instruction::InsertElement:
3367 case llvm::Instruction::ShuffleVector:
3368 case llvm::Instruction::ExtractValue:
3369 case llvm::Instruction::InsertValue:
3370 case llvm::Instruction::LandingPad:
3371 case llvm::Instruction::IndirectBr:
3372 case llvm::Instruction::Load:
3373 case llvm::Instruction::Store:
3374 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3375
3376 default:
3377 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3378 break;
buzbeead8f15e2012-06-18 14:49:45 -07003379 }
3380 }
buzbee2cfc6392012-05-07 14:51:40 -07003381
buzbee0967a252012-09-14 10:43:54 -07003382 if (headLIR != NULL) {
3383 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
buzbee2cfc6392012-05-07 14:51:40 -07003384 }
buzbee0967a252012-09-14 10:43:54 -07003385 if (nextBB != NULL) {
3386 bb = nextBB;
3387 nextBB = NULL;
buzbee6969d502012-06-15 16:40:31 -07003388 }
buzbee6969d502012-06-15 16:40:31 -07003389 }
buzbee2cfc6392012-05-07 14:51:40 -07003390 return false;
3391}
3392
3393/*
3394 * Convert LLVM_IR to MIR:
3395 * o Iterate through the LLVM_IR and construct a graph using
3396 * standard MIR building blocks.
3397 * o Perform a basic-block optimization pass to remove unnecessary
3398 * store/load sequences.
3399 * o Convert the LLVM Value operands into RegLocations where applicable.
3400 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3401 * o Perform register promotion
3402 * o Iterate through the graph a basic block at a time, generating
3403 * LIR.
3404 * o Assemble LIR as usual.
3405 * o Profit.
3406 */
3407void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3408{
buzbeead8f15e2012-06-18 14:49:45 -07003409 llvm::Function* func = cUnit->func;
3410 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003411 // Allocate a list for LIR basic block labels
3412 cUnit->blockLabelList =
buzbeecbd6d442012-11-17 14:11:25 -08003413 static_cast<LIR*>(oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR));
buzbeea1da8a52012-07-09 14:00:21 -07003414 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003415 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003416 for (llvm::Function::iterator i = func->begin(),
3417 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003418 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3419 &labelList[nextLabel++]);
3420 }
buzbeead8f15e2012-06-18 14:49:45 -07003421
3422 /*
3423 * Keep honest - clear regLocations, Value => RegLocation,
3424 * promotion map and VmapTables.
3425 */
3426 cUnit->locMap.clear(); // Start fresh
3427 cUnit->regLocation = NULL;
3428 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3429 i++) {
3430 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3431 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3432 }
3433 cUnit->coreSpillMask = 0;
3434 cUnit->numCoreSpills = 0;
3435 cUnit->fpSpillMask = 0;
3436 cUnit->numFPSpills = 0;
3437 cUnit->coreVmapTable.clear();
3438 cUnit->fpVmapTable.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003439
3440 /*
3441 * At this point, we've lost all knowledge of register promotion.
3442 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003443 * exists - not required for correctness). Normally, this will
3444 * be the first instruction we encounter, so we won't have to iterate
3445 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003446 */
buzbeeca7a5e42012-08-20 11:12:18 -07003447 for (llvm::inst_iterator i = llvm::inst_begin(func),
3448 e = llvm::inst_end(func); i != e; ++i) {
3449 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(&*i);
3450 if (callInst != NULL) {
3451 llvm::Function* callee = callInst->getCalledFunction();
3452 greenland::IntrinsicHelper::IntrinsicId id =
3453 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3454 if (id == greenland::IntrinsicHelper::MethodInfo) {
3455 if (cUnit->printMe) {
3456 LOG(INFO) << "Found MethodInfo";
3457 }
3458 llvm::MDNode* regInfoNode = callInst->getMetadata("RegInfo");
3459 if (regInfoNode != NULL) {
3460 llvm::ConstantInt* numInsValue =
3461 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(0));
3462 llvm::ConstantInt* numRegsValue =
3463 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(1));
3464 llvm::ConstantInt* numOutsValue =
3465 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(2));
3466 llvm::ConstantInt* numCompilerTempsValue =
3467 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(3));
3468 llvm::ConstantInt* numSSARegsValue =
3469 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(4));
3470 if (cUnit->printMe) {
3471 LOG(INFO) << "RegInfo - Ins:" << numInsValue->getZExtValue()
3472 << ", Regs:" << numRegsValue->getZExtValue()
3473 << ", Outs:" << numOutsValue->getZExtValue()
3474 << ", CTemps:" << numCompilerTempsValue->getZExtValue()
3475 << ", SSARegs:" << numSSARegsValue->getZExtValue();
3476 }
3477 }
3478 llvm::MDNode* pmapInfoNode = callInst->getMetadata("PromotionMap");
3479 if (pmapInfoNode != NULL) {
3480 int elems = pmapInfoNode->getNumOperands();
3481 if (cUnit->printMe) {
3482 LOG(INFO) << "PMap size: " << elems;
3483 }
3484 for (int i = 0; i < elems; i++) {
3485 llvm::ConstantInt* rawMapData =
3486 static_cast<llvm::ConstantInt*>(pmapInfoNode->getOperand(i));
3487 uint32_t mapData = rawMapData->getZExtValue();
3488 PromotionMap* p = &cUnit->promotionMap[i];
3489 p->firstInPair = (mapData >> 24) & 0xff;
3490 p->fpReg = (mapData >> 16) & 0xff;
3491 p->coreReg = (mapData >> 8) & 0xff;
3492 p->fpLocation = static_cast<RegLocationType>((mapData >> 4) & 0xf);
3493 if (p->fpLocation == kLocPhysReg) {
3494 oatRecordFpPromotion(cUnit, p->fpReg, i);
3495 }
3496 p->coreLocation = static_cast<RegLocationType>(mapData & 0xf);
3497 if (p->coreLocation == kLocPhysReg) {
3498 oatRecordCorePromotion(cUnit, p->coreReg, i);
3499 }
3500 }
3501 if (cUnit->printMe) {
3502 oatDumpPromotionMap(cUnit);
3503 }
3504 }
3505 break;
3506 }
3507 }
3508 }
3509 oatAdjustSpillMask(cUnit);
3510 cUnit->frameSize = oatComputeFrameSize(cUnit);
buzbeead8f15e2012-06-18 14:49:45 -07003511
3512 // Create RegLocations for arguments
3513 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3514 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3515 for (; it != it_end; ++it) {
3516 llvm::Value* val = it;
3517 createLocFromValue(cUnit, val);
3518 }
3519 // Create RegLocations for all non-argument defintions
3520 for (llvm::inst_iterator i = llvm::inst_begin(func),
3521 e = llvm::inst_end(func); i != e; ++i) {
3522 llvm::Value* val = &*i;
3523 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3524 createLocFromValue(cUnit, val);
3525 }
3526 }
3527
buzbee2cfc6392012-05-07 14:51:40 -07003528 // Walk the blocks, generating code.
3529 for (llvm::Function::iterator i = cUnit->func->begin(),
3530 e = cUnit->func->end(); i != e; ++i) {
3531 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3532 }
3533
3534 handleSuspendLaunchpads(cUnit);
3535
3536 handleThrowLaunchpads(cUnit);
3537
3538 handleIntrinsicLaunchpads(cUnit);
3539
buzbee692be802012-08-29 15:52:59 -07003540 cUnit->func->eraseFromParent();
3541 cUnit->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003542}
3543
3544
3545} // namespace art