blob: 2996e9a29f740658a2579f9cf7e534ba175bd62a [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
buzbeeeaf09bc2012-11-15 14:51:41 -080030#include "method_codegen_driver.h"
31#include "local_optimizations.h"
32
buzbee8320f382012-09-11 16:29:42 -070033static const char* kLabelFormat = "%c0x%x_%d";
buzbee951c0a12012-10-03 16:31:39 -070034static const char kInvalidBlock = 0xff;
buzbee8320f382012-09-11 16:29:42 -070035static const char kNormalBlock = 'L';
36static const char kCatchBlock = 'C';
buzbee2cfc6392012-05-07 14:51:40 -070037
38namespace art {
39extern const RegLocation badLoc;
buzbeeb03f4872012-06-11 15:22:11 -070040RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070041
42llvm::BasicBlock* getLLVMBlock(CompilationUnit* cUnit, int id)
43{
44 return cUnit->idToBlockMap.Get(id);
45}
46
47llvm::Value* getLLVMValue(CompilationUnit* cUnit, int sReg)
48{
buzbeecbd6d442012-11-17 14:11:25 -080049 return reinterpret_cast<llvm::Value*>(oatGrowableListGetElement(&cUnit->llvmValues, sReg));
buzbee2cfc6392012-05-07 14:51:40 -070050}
51
52// Replace the placeholder value with the real definition
53void defineValue(CompilationUnit* cUnit, llvm::Value* val, int sReg)
54{
55 llvm::Value* placeholder = getLLVMValue(cUnit, sReg);
buzbee9a2487f2012-07-26 14:01:13 -070056 if (placeholder == NULL) {
57 // This can happen on instruction rewrite on verification failure
Bill Buzbeec9f40dd2012-08-15 11:35:25 -070058 LOG(WARNING) << "Null placeholder";
buzbee9a2487f2012-07-26 14:01:13 -070059 return;
60 }
buzbee2cfc6392012-05-07 14:51:40 -070061 placeholder->replaceAllUsesWith(val);
62 val->takeName(placeholder);
buzbeecbd6d442012-11-17 14:11:25 -080063 cUnit->llvmValues.elemList[sReg] = reinterpret_cast<uintptr_t>(val);
buzbee4be777b2012-07-12 14:38:18 -070064 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
65 DCHECK(inst != NULL);
66 inst->eraseFromParent();
TDYa1278e950c12012-11-02 09:58:19 -070067
68 // Set vreg for debugging
69 if (!cUnit->compiler->IsDebuggingSupported()) {
70 greenland::IntrinsicHelper::IntrinsicId id =
71 greenland::IntrinsicHelper::SetVReg;
72 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
73 int vReg = SRegToVReg(cUnit, sReg);
74 llvm::Value* tableSlot = cUnit->irb->getInt32(vReg);
75 llvm::Value* args[] = { tableSlot, val };
76 cUnit->irb->CreateCall(func, args);
77 }
buzbee2cfc6392012-05-07 14:51:40 -070078}
79
80llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
81{
82 llvm::Type* res = NULL;
83 if (loc.wide) {
84 if (loc.fp)
buzbee4f1181f2012-06-22 13:52:12 -070085 res = cUnit->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070086 else
buzbee4f1181f2012-06-22 13:52:12 -070087 res = cUnit->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070088 } else {
89 if (loc.fp) {
buzbee4f1181f2012-06-22 13:52:12 -070090 res = cUnit->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070091 } else {
92 if (loc.ref)
93 res = cUnit->irb->GetJObjectTy();
94 else
buzbee4f1181f2012-06-22 13:52:12 -070095 res = cUnit->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -070096 }
97 }
98 return res;
99}
100
buzbeead8f15e2012-06-18 14:49:45 -0700101/* Create an in-memory RegLocation from an llvm Value. */
102void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
103{
104 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
105 std::string s(val->getName().str());
106 const char* valName = s.c_str();
buzbeead8f15e2012-06-18 14:49:45 -0700107 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
108 DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
109 int baseSReg = INVALID_SREG;
110 int subscript = -1;
111 sscanf(valName, "v%d_%d", &baseSReg, &subscript);
112 if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
113 baseSReg = SSA_METHOD_BASEREG;
114 subscript = 0;
115 }
buzbeead8f15e2012-06-18 14:49:45 -0700116 DCHECK_NE(baseSReg, INVALID_SREG);
117 DCHECK_NE(subscript, -1);
118 // TODO: redo during C++'ification
119 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
120 INVALID_REG, INVALID_SREG, INVALID_SREG};
121 llvm::Type* ty = val->getType();
122 loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
123 (ty == cUnit->irb->getDoubleTy()));
124 loc.defined = true;
buzbeeca7a5e42012-08-20 11:12:18 -0700125 loc.home = false; // May change during promotion
buzbeead8f15e2012-06-18 14:49:45 -0700126 loc.sRegLow = baseSReg;
127 loc.origSReg = cUnit->locMap.size();
buzbeeca7a5e42012-08-20 11:12:18 -0700128 PromotionMap pMap = cUnit->promotionMap[baseSReg];
129 if (ty == cUnit->irb->getFloatTy()) {
130 loc.fp = true;
131 if (pMap.fpLocation == kLocPhysReg) {
132 loc.lowReg = pMap.fpReg;
133 loc.location = kLocPhysReg;
134 loc.home = true;
135 }
136 } else if (ty == cUnit->irb->getDoubleTy()) {
137 loc.fp = true;
138 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
139 if ((pMap.fpLocation == kLocPhysReg) &&
140 (pMapHigh.fpLocation == kLocPhysReg) &&
141 ((pMap.fpReg & 0x1) == 0) &&
142 (pMap.fpReg + 1 == pMapHigh.fpReg)) {
143 loc.lowReg = pMap.fpReg;
144 loc.highReg = pMapHigh.fpReg;
145 loc.location = kLocPhysReg;
146 loc.home = true;
147 }
148 } else if (ty == cUnit->irb->GetJObjectTy()) {
149 loc.ref = true;
150 if (pMap.coreLocation == kLocPhysReg) {
151 loc.lowReg = pMap.coreReg;
152 loc.location = kLocPhysReg;
153 loc.home = true;
154 }
155 } else if (ty == cUnit->irb->getInt64Ty()) {
156 loc.core = true;
157 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
158 if ((pMap.coreLocation == kLocPhysReg) &&
159 (pMapHigh.coreLocation == kLocPhysReg)) {
160 loc.lowReg = pMap.coreReg;
161 loc.highReg = pMapHigh.coreReg;
162 loc.location = kLocPhysReg;
163 loc.home = true;
164 }
165 } else {
166 loc.core = true;
167 if (pMap.coreLocation == kLocPhysReg) {
168 loc.lowReg = pMap.coreReg;
169 loc.location = kLocPhysReg;
170 loc.home = true;
171 }
172 }
173
174 if (cUnit->printMe && loc.home) {
175 if (loc.wide) {
buzbeecbd6d442012-11-17 14:11:25 -0800176 LOG(INFO) << "Promoted wide " << s << " to regs " << loc.lowReg << "/" << loc.highReg;
buzbeeca7a5e42012-08-20 11:12:18 -0700177 } else {
buzbeecbd6d442012-11-17 14:11:25 -0800178 LOG(INFO) << "Promoted " << s << " to reg " << loc.lowReg;
buzbeeca7a5e42012-08-20 11:12:18 -0700179 }
180 }
buzbeead8f15e2012-06-18 14:49:45 -0700181 cUnit->locMap.Put(val, loc);
182}
buzbee2cfc6392012-05-07 14:51:40 -0700183void initIR(CompilationUnit* cUnit)
184{
buzbee4df2bbd2012-10-11 14:46:06 -0700185 LLVMInfo* llvmInfo = cUnit->llvm_info;
186 if (llvmInfo == NULL) {
187 CompilerTls* tls = cUnit->compiler->GetTls();
188 CHECK(tls != NULL);
189 llvmInfo = static_cast<LLVMInfo*>(tls->GetLLVMInfo());
190 if (llvmInfo == NULL) {
191 llvmInfo = new LLVMInfo();
192 tls->SetLLVMInfo(llvmInfo);
193 }
194 }
195 cUnit->context = llvmInfo->GetLLVMContext();
196 cUnit->module = llvmInfo->GetLLVMModule();
197 cUnit->intrinsic_helper = llvmInfo->GetIntrinsicHelper();
198 cUnit->irb = llvmInfo->GetIRBuilder();
buzbee2cfc6392012-05-07 14:51:40 -0700199}
200
201const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
202 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
203}
204
buzbeef58c12c2012-07-03 15:06:29 -0700205llvm::BasicBlock* findCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
206{
207 BasicBlock* bb = oatFindBlock(cUnit, vaddr);
208 DCHECK(bb != NULL);
209 return getLLVMBlock(cUnit, bb->id);
210}
211
212void convertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
213 int32_t tableOffset, RegLocation rlSrc)
214{
215 const Instruction::PackedSwitchPayload* payload =
216 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
217 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
218
219 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
220
221 llvm::SwitchInst* sw =
222 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
223 payload->case_count);
224
225 for (uint16_t i = 0; i < payload->case_count; ++i) {
226 llvm::BasicBlock* llvmBB =
227 findCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
228 sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
229 }
230 llvm::MDNode* switchNode =
231 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
232 sw->setMetadata("SwitchTable", switchNode);
233 bb->taken = NULL;
234 bb->fallThrough = NULL;
235}
236
buzbeea1da8a52012-07-09 14:00:21 -0700237void convertSparseSwitch(CompilationUnit* cUnit, BasicBlock* bb,
238 int32_t tableOffset, RegLocation rlSrc)
239{
240 const Instruction::SparseSwitchPayload* payload =
241 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
242 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
243
244 const int32_t* keys = payload->GetKeys();
245 const int32_t* targets = payload->GetTargets();
246
247 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
248
249 llvm::SwitchInst* sw =
250 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
251 payload->case_count);
252
253 for (size_t i = 0; i < payload->case_count; ++i) {
254 llvm::BasicBlock* llvmBB =
255 findCaseTarget(cUnit, cUnit->currentDalvikOffset + targets[i]);
256 sw->addCase(cUnit->irb->getInt32(keys[i]), llvmBB);
257 }
258 llvm::MDNode* switchNode =
259 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
260 sw->setMetadata("SwitchTable", switchNode);
261 bb->taken = NULL;
262 bb->fallThrough = NULL;
263}
264
buzbee8fa0fda2012-06-27 15:44:52 -0700265void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
266 greenland::IntrinsicHelper::IntrinsicId id,
267 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700268{
buzbee8fa0fda2012-06-27 15:44:52 -0700269 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700270 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700271 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
272 defineValue(cUnit, res, rlDest.origSReg);
273}
274
275void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
276 greenland::IntrinsicHelper::IntrinsicId id,
277 RegLocation rlSrc)
278{
279 llvm::SmallVector<llvm::Value*, 2> args;
280 args.push_back(cUnit->irb->getInt32(fieldIndex));
281 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
282 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
283 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700284}
285
buzbee101305f2012-06-28 18:00:56 -0700286void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
287 RegLocation rlArray)
288{
289 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700290 id = greenland::IntrinsicHelper::HLFillArrayData;
buzbee101305f2012-06-28 18:00:56 -0700291 llvm::SmallVector<llvm::Value*, 2> args;
292 args.push_back(cUnit->irb->getInt32(offset));
293 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
294 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
295 cUnit->irb->CreateCall(intr, args);
296}
297
buzbee2cfc6392012-05-07 14:51:40 -0700298llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
299 RegLocation loc)
300{
301 greenland::IntrinsicHelper::IntrinsicId id;
302 if (loc.wide) {
303 if (loc.fp) {
304 id = greenland::IntrinsicHelper::ConstDouble;
305 } else {
306 id = greenland::IntrinsicHelper::ConstLong;
307 }
308 } else {
309 if (loc.fp) {
310 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700311 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700312 id = greenland::IntrinsicHelper::ConstObj;
313 } else {
314 id = greenland::IntrinsicHelper::ConstInt;
315 }
316 }
317 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
318 return cUnit->irb->CreateCall(intr, src);
319}
buzbeeb03f4872012-06-11 15:22:11 -0700320
321void emitPopShadowFrame(CompilationUnit* cUnit)
322{
323 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
324 greenland::IntrinsicHelper::PopShadowFrame);
325 cUnit->irb->CreateCall(intr);
326}
327
buzbee2cfc6392012-05-07 14:51:40 -0700328llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
329 RegLocation loc)
330{
331 greenland::IntrinsicHelper::IntrinsicId id;
332 if (loc.wide) {
333 if (loc.fp) {
334 id = greenland::IntrinsicHelper::CopyDouble;
335 } else {
336 id = greenland::IntrinsicHelper::CopyLong;
337 }
338 } else {
339 if (loc.fp) {
340 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700341 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700342 id = greenland::IntrinsicHelper::CopyObj;
343 } else {
344 id = greenland::IntrinsicHelper::CopyInt;
345 }
346 }
347 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
348 return cUnit->irb->CreateCall(intr, src);
349}
350
buzbee32412962012-06-26 16:27:56 -0700351void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
352{
353 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
354 greenland::IntrinsicHelper::GetException);
355 llvm::Value* res = cUnit->irb->CreateCall(func);
356 defineValue(cUnit, res, rlDest.origSReg);
357}
358
359void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
360{
361 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
362 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
TDYa127f71bf5a2012-07-29 20:09:52 -0700363 greenland::IntrinsicHelper::HLThrowException);
buzbee32412962012-06-26 16:27:56 -0700364 cUnit->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700365}
366
buzbee8fa0fda2012-06-27 15:44:52 -0700367void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
368 greenland::IntrinsicHelper::IntrinsicId id,
369 RegLocation rlSrc)
370{
371 llvm::SmallVector<llvm::Value*, 2> args;
372 args.push_back(cUnit->irb->getInt32(optFlags));
373 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
374 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
375 cUnit->irb->CreateCall(func, args);
376}
377
buzbee76592632012-06-29 15:18:35 -0700378void convertArrayLength(CompilationUnit* cUnit, int optFlags,
379 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700380{
381 llvm::SmallVector<llvm::Value*, 2> args;
382 args.push_back(cUnit->irb->getInt32(optFlags));
383 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
384 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700385 greenland::IntrinsicHelper::OptArrayLength);
buzbee76592632012-06-29 15:18:35 -0700386 llvm::Value* res = cUnit->irb->CreateCall(func, args);
387 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700388}
389
buzbee2cfc6392012-05-07 14:51:40 -0700390void emitSuspendCheck(CompilationUnit* cUnit)
391{
392 greenland::IntrinsicHelper::IntrinsicId id =
393 greenland::IntrinsicHelper::CheckSuspend;
394 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
395 cUnit->irb->CreateCall(intr);
396}
397
398llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
399 llvm::Value* src1, llvm::Value* src2)
400{
401 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700402 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700403 switch(cc) {
404 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
405 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
406 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
407 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
408 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
409 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
410 default: LOG(FATAL) << "Unexpected cc value " << cc;
411 }
412 return res;
413}
414
415void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
416 ConditionCode cc, RegLocation rlSrc1,
417 RegLocation rlSrc2)
418{
419 if (bb->taken->startOffset <= mir->offset) {
420 emitSuspendCheck(cUnit);
421 }
422 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
423 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
424 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
425 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
426 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
427 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700428 // Don't redo the fallthrough branch in the BB driver
429 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700430}
431
432void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
433 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
434{
435 if (bb->taken->startOffset <= mir->offset) {
436 emitSuspendCheck(cUnit);
437 }
438 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
439 llvm::Value* src2;
440 if (rlSrc1.ref) {
441 src2 = cUnit->irb->GetJNull();
442 } else {
443 src2 = cUnit->irb->getInt32(0);
444 }
445 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700446 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
447 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700448 // Don't redo the fallthrough branch in the BB driver
449 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700450}
451
452llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
453 llvm::Value* src1, llvm::Value* src2)
454{
455 greenland::IntrinsicHelper::IntrinsicId id;
456 if (isLong) {
457 if (isDiv) {
458 id = greenland::IntrinsicHelper::DivLong;
459 } else {
460 id = greenland::IntrinsicHelper::RemLong;
461 }
Logan Chien554e6072012-07-23 20:00:01 -0700462 } else {
463 if (isDiv) {
buzbee2cfc6392012-05-07 14:51:40 -0700464 id = greenland::IntrinsicHelper::DivInt;
465 } else {
466 id = greenland::IntrinsicHelper::RemInt;
Logan Chien554e6072012-07-23 20:00:01 -0700467 }
buzbee2cfc6392012-05-07 14:51:40 -0700468 }
469 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
470 llvm::SmallVector<llvm::Value*, 2>args;
471 args.push_back(src1);
472 args.push_back(src2);
473 return cUnit->irb->CreateCall(intr, args);
474}
475
476llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
477 llvm::Value* src1, llvm::Value* src2)
478{
479 llvm::Value* res = NULL;
480 switch(op) {
481 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
482 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700483 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700484 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
485 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
486 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
487 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
488 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
489 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700490 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
491 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
492 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700493 default:
494 LOG(FATAL) << "Invalid op " << op;
495 }
496 return res;
497}
498
499void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
500 RegLocation rlSrc1, RegLocation rlSrc2)
501{
502 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
503 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
504 llvm::Value* res = NULL;
505 switch(op) {
506 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
507 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
508 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
509 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
510 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
511 default:
512 LOG(FATAL) << "Invalid op " << op;
513 }
514 defineValue(cUnit, res, rlDest.origSReg);
515}
516
buzbee2a83e8f2012-07-13 16:42:30 -0700517void convertShift(CompilationUnit* cUnit,
518 greenland::IntrinsicHelper::IntrinsicId id,
519 RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
buzbee4f1181f2012-06-22 13:52:12 -0700520{
buzbee2a83e8f2012-07-13 16:42:30 -0700521 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
522 llvm::SmallVector<llvm::Value*, 2>args;
523 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
524 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
525 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
526 defineValue(cUnit, res, rlDest.origSReg);
527}
528
529void convertShiftLit(CompilationUnit* cUnit,
530 greenland::IntrinsicHelper::IntrinsicId id,
531 RegLocation rlDest, RegLocation rlSrc, int shiftAmount)
532{
533 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
534 llvm::SmallVector<llvm::Value*, 2>args;
535 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
536 args.push_back(cUnit->irb->getInt32(shiftAmount));
537 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700538 defineValue(cUnit, res, rlDest.origSReg);
539}
540
buzbee2cfc6392012-05-07 14:51:40 -0700541void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
542 RegLocation rlSrc1, RegLocation rlSrc2)
543{
544 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
545 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700546 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700547 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
548 defineValue(cUnit, res, rlDest.origSReg);
549}
550
buzbeeb03f4872012-06-11 15:22:11 -0700551void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
552{
553 int index = -1;
554 DCHECK(newVal != NULL);
555 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
556 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
557 if (cUnit->shadowMap[i] == vReg) {
558 index = i;
559 break;
560 }
561 }
TDYa127347166a2012-08-23 12:23:44 -0700562 if (index == -1) {
563 return;
564 }
buzbee6459e7c2012-10-02 14:42:41 -0700565 llvm::Type* ty = newVal->getType();
buzbeeb03f4872012-06-11 15:22:11 -0700566 greenland::IntrinsicHelper::IntrinsicId id =
567 greenland::IntrinsicHelper::SetShadowFrameEntry;
568 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
569 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
buzbee6459e7c2012-10-02 14:42:41 -0700570 // If newVal is a Null pointer, we'll see it here as a const int. Replace
571 if (!ty->isPointerTy()) {
572 // TODO: assert newVal created w/ dex_lang_const_int(0) or dex_lang_const_float(0)
573 newVal = cUnit->irb->GetJNull();
574 }
buzbeeb03f4872012-06-11 15:22:11 -0700575 llvm::Value* args[] = { newVal, tableSlot };
576 cUnit->irb->CreateCall(func, args);
577}
578
buzbee2cfc6392012-05-07 14:51:40 -0700579void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
580 RegLocation rlSrc1, int32_t imm)
581{
582 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
583 llvm::Value* src2 = cUnit->irb->getInt32(imm);
584 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
585 defineValue(cUnit, res, rlDest.origSReg);
586}
587
buzbee101305f2012-06-28 18:00:56 -0700588/*
589 * Process arguments for invoke. Note: this code is also used to
590 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
591 * The requirements are similar.
592 */
buzbee6969d502012-06-15 16:40:31 -0700593void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700594 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700595{
596 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
597 llvm::SmallVector<llvm::Value*, 10> args;
598 // Insert the invokeType
599 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
600 // Insert the method_idx
601 args.push_back(cUnit->irb->getInt32(info->index));
602 // Insert the optimization flags
603 args.push_back(cUnit->irb->getInt32(info->optFlags));
604 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700605 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700606 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
607 args.push_back(val);
608 i += info->args[i].wide ? 2 : 1;
609 }
610 /*
611 * Choose the invoke return type based on actual usage. Note: may
612 * be different than shorty. For example, if a function return value
613 * is not used, we'll treat this as a void invoke.
614 */
615 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700616 if (isFilledNewArray) {
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700617 id = greenland::IntrinsicHelper::HLFilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700618 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700619 id = greenland::IntrinsicHelper::HLInvokeVoid;
620 } else {
621 if (info->result.wide) {
622 if (info->result.fp) {
623 id = greenland::IntrinsicHelper::HLInvokeDouble;
624 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700625 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700626 }
627 } else if (info->result.ref) {
628 id = greenland::IntrinsicHelper::HLInvokeObj;
629 } else if (info->result.fp) {
630 id = greenland::IntrinsicHelper::HLInvokeFloat;
631 } else {
632 id = greenland::IntrinsicHelper::HLInvokeInt;
633 }
634 }
635 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
636 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
637 if (info->result.location != kLocInvalid) {
638 defineValue(cUnit, res, info->result.origSReg);
TDYa127890ea892012-08-22 10:49:42 -0700639 if (info->result.ref) {
buzbeecbd6d442012-11-17 14:11:25 -0800640 setShadowFrameEntry(cUnit, reinterpret_cast<llvm::Value*>
641 (cUnit->llvmValues.elemList[info->result.origSReg]));
TDYa127890ea892012-08-22 10:49:42 -0700642 }
buzbee6969d502012-06-15 16:40:31 -0700643 }
644}
645
buzbee101305f2012-06-28 18:00:56 -0700646void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
647 greenland::IntrinsicHelper::IntrinsicId id,
648 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700649{
buzbee6969d502012-06-15 16:40:31 -0700650 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700651 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700652 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
653 defineValue(cUnit, res, rlDest.origSReg);
654}
655
buzbee101305f2012-06-28 18:00:56 -0700656void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
657 RegLocation rlSrc)
658{
659 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700660 id = greenland::IntrinsicHelper::HLCheckCast;
buzbee101305f2012-06-28 18:00:56 -0700661 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
662 llvm::SmallVector<llvm::Value*, 2> args;
663 args.push_back(cUnit->irb->getInt32(type_idx));
664 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
665 cUnit->irb->CreateCall(intr, args);
666}
667
buzbee8fa0fda2012-06-27 15:44:52 -0700668void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
669 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700670{
671 greenland::IntrinsicHelper::IntrinsicId id;
672 id = greenland::IntrinsicHelper::NewInstance;
673 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
674 llvm::Value* index = cUnit->irb->getInt32(type_idx);
675 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
676 defineValue(cUnit, res, rlDest.origSReg);
677}
678
buzbee8fa0fda2012-06-27 15:44:52 -0700679void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
680 RegLocation rlDest, RegLocation rlSrc)
681{
682 greenland::IntrinsicHelper::IntrinsicId id;
683 id = greenland::IntrinsicHelper::NewArray;
684 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
685 llvm::SmallVector<llvm::Value*, 2> args;
686 args.push_back(cUnit->irb->getInt32(type_idx));
687 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
688 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
689 defineValue(cUnit, res, rlDest.origSReg);
690}
691
692void convertAget(CompilationUnit* cUnit, int optFlags,
693 greenland::IntrinsicHelper::IntrinsicId id,
694 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
695{
696 llvm::SmallVector<llvm::Value*, 3> args;
697 args.push_back(cUnit->irb->getInt32(optFlags));
698 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
699 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
700 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
701 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
702 defineValue(cUnit, res, rlDest.origSReg);
703}
704
705void convertAput(CompilationUnit* cUnit, int optFlags,
706 greenland::IntrinsicHelper::IntrinsicId id,
707 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
708{
709 llvm::SmallVector<llvm::Value*, 4> args;
710 args.push_back(cUnit->irb->getInt32(optFlags));
711 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
712 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
713 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
714 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
715 cUnit->irb->CreateCall(intr, args);
716}
717
buzbee101305f2012-06-28 18:00:56 -0700718void convertIget(CompilationUnit* cUnit, int optFlags,
719 greenland::IntrinsicHelper::IntrinsicId id,
720 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
721{
722 llvm::SmallVector<llvm::Value*, 3> args;
723 args.push_back(cUnit->irb->getInt32(optFlags));
724 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
725 args.push_back(cUnit->irb->getInt32(fieldIndex));
726 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
727 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
728 defineValue(cUnit, res, rlDest.origSReg);
729}
730
731void convertIput(CompilationUnit* cUnit, int optFlags,
732 greenland::IntrinsicHelper::IntrinsicId id,
733 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
734{
735 llvm::SmallVector<llvm::Value*, 4> args;
736 args.push_back(cUnit->irb->getInt32(optFlags));
737 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
738 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
739 args.push_back(cUnit->irb->getInt32(fieldIndex));
740 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
741 cUnit->irb->CreateCall(intr, args);
742}
743
buzbee8fa0fda2012-06-27 15:44:52 -0700744void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
745 RegLocation rlDest, RegLocation rlSrc)
746{
747 greenland::IntrinsicHelper::IntrinsicId id;
748 id = greenland::IntrinsicHelper::InstanceOf;
749 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
750 llvm::SmallVector<llvm::Value*, 2> args;
751 args.push_back(cUnit->irb->getInt32(type_idx));
752 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
753 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
754 defineValue(cUnit, res, rlDest.origSReg);
755}
756
buzbee101305f2012-06-28 18:00:56 -0700757void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
758 RegLocation rlSrc)
759{
760 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
761 cUnit->irb->getInt64Ty());
762 defineValue(cUnit, res, rlDest.origSReg);
763}
764
buzbee76592632012-06-29 15:18:35 -0700765void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
766 RegLocation rlSrc)
767{
768 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
769 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
770 defineValue(cUnit, res, rlDest.origSReg);
771}
772
773void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
774 RegLocation rlSrc)
775{
776 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
777 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
778 defineValue(cUnit, res, rlDest.origSReg);
779}
780
781void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
782 RegLocation rlSrc)
783{
784 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
785 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
786 defineValue(cUnit, res, rlDest.origSReg);
787}
788
789void convertWideComparison(CompilationUnit* cUnit,
790 greenland::IntrinsicHelper::IntrinsicId id,
791 RegLocation rlDest, RegLocation rlSrc1,
792 RegLocation rlSrc2)
793{
794 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
795 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
796 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
797 llvm::SmallVector<llvm::Value*, 2> args;
798 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
799 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
800 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
801 defineValue(cUnit, res, rlDest.origSReg);
802}
803
buzbee101305f2012-06-28 18:00:56 -0700804void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
805 RegLocation rlSrc,
806 greenland::IntrinsicHelper::IntrinsicId id)
807{
808 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700809 llvm::Value* res =
810 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
811 defineValue(cUnit, res, rlDest.origSReg);
812}
813
814void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
815 RegLocation rlSrc)
816{
817 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
818 defineValue(cUnit, res, rlDest.origSReg);
819}
820
821void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
822 RegLocation rlSrc)
823{
824 llvm::Value* res =
825 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
826 defineValue(cUnit, res, rlDest.origSReg);
827}
828
TDYa1274ec8ccd2012-08-11 07:04:57 -0700829void convertFPToInt(CompilationUnit* cUnit,
830 greenland::IntrinsicHelper::IntrinsicId id,
831 RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700832 RegLocation rlSrc)
833{
TDYa1274ec8ccd2012-08-11 07:04:57 -0700834 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
835 llvm::Value* res = cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
buzbee76592632012-06-29 15:18:35 -0700836 defineValue(cUnit, res, rlDest.origSReg);
837}
838
839
840void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
841 RegLocation rlSrc)
842{
843 llvm::Value* res =
844 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
845 defineValue(cUnit, res, rlDest.origSReg);
846}
847
848void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
849 RegLocation rlSrc)
850{
851 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
852 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700853 defineValue(cUnit, res, rlDest.origSReg);
854}
855
buzbee2cfc6392012-05-07 14:51:40 -0700856/*
857 * Target-independent code generation. Use only high-level
858 * load/store utilities here, or target-dependent genXX() handlers
859 * when necessary.
860 */
861bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
862 llvm::BasicBlock* llvmBB, LIR* labelList)
863{
864 bool res = false; // Assume success
865 RegLocation rlSrc[3];
866 RegLocation rlDest = badLoc;
buzbee2cfc6392012-05-07 14:51:40 -0700867 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbeecbd6d442012-11-17 14:11:25 -0800868 int opVal = opcode;
buzbee6969d502012-06-15 16:40:31 -0700869 uint32_t vB = mir->dalvikInsn.vB;
870 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700871 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700872
buzbeeb03f4872012-06-11 15:22:11 -0700873 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700874
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700875 if (cUnit->printMe) {
buzbeecbd6d442012-11-17 14:11:25 -0800876 if (opVal < kMirOpFirst) {
877 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x" << std::hex << opVal;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700878 } else {
buzbeecbd6d442012-11-17 14:11:25 -0800879 LOG(INFO) << extendedMIROpNames[opVal - kMirOpFirst] << " 0x" << std::hex << opVal;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700880 }
881 }
882
buzbee2cfc6392012-05-07 14:51:40 -0700883 /* Prep Src and Dest locations */
884 int nextSreg = 0;
885 int nextLoc = 0;
886 int attrs = oatDataFlowAttributes[opcode];
887 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
888 if (attrs & DF_UA) {
889 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700890 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700891 nextSreg+= 2;
892 } else {
893 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
894 nextSreg++;
895 }
896 }
897 if (attrs & DF_UB) {
898 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700899 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700900 nextSreg+= 2;
901 } else {
902 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
903 nextSreg++;
904 }
905 }
906 if (attrs & DF_UC) {
907 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700908 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700909 } else {
910 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
911 }
912 }
913 if (attrs & DF_DA) {
914 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700915 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700916 } else {
buzbee15bf9802012-06-12 17:49:27 -0700917 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700918 if (rlDest.ref) {
919 objectDefinition = true;
920 }
buzbee2cfc6392012-05-07 14:51:40 -0700921 }
922 }
923
924 switch (opcode) {
925 case Instruction::NOP:
926 break;
927
928 case Instruction::MOVE:
929 case Instruction::MOVE_OBJECT:
930 case Instruction::MOVE_16:
931 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700932 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700933 case Instruction::MOVE_FROM16:
934 case Instruction::MOVE_WIDE:
935 case Instruction::MOVE_WIDE_16:
936 case Instruction::MOVE_WIDE_FROM16: {
937 /*
938 * Moves/copies are meaningless in pure SSA register form,
939 * but we need to preserve them for the conversion back into
940 * MIR (at least until we stop using the Dalvik register maps).
941 * Insert a dummy intrinsic copy call, which will be recognized
942 * by the quick path and removed by the portable path.
943 */
944 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
945 llvm::Value* res = emitCopy(cUnit, src, rlDest);
946 defineValue(cUnit, res, rlDest.origSReg);
947 }
948 break;
949
950 case Instruction::CONST:
951 case Instruction::CONST_4:
952 case Instruction::CONST_16: {
TDYa127347166a2012-08-23 12:23:44 -0700953 if (vB == 0) {
954 objectDefinition = true;
955 }
buzbee6969d502012-06-15 16:40:31 -0700956 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700957 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
958 defineValue(cUnit, res, rlDest.origSReg);
959 }
960 break;
961
962 case Instruction::CONST_WIDE_16:
963 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700964 // Sign extend to 64 bits
965 int64_t imm = static_cast<int32_t>(vB);
966 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700967 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
968 defineValue(cUnit, res, rlDest.origSReg);
969 }
970 break;
971
972 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700973 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700974 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
975 defineValue(cUnit, res, rlDest.origSReg);
976 }
977 break;
978
979 case Instruction::CONST_WIDE: {
980 llvm::Constant* immValue =
981 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
982 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
983 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700984 }
985 break;
buzbee2cfc6392012-05-07 14:51:40 -0700986 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700987 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700988 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
989 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
990 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700991 }
992 break;
993
buzbee8fa0fda2012-06-27 15:44:52 -0700994 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700995 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700996 rlSrc[0]);
997 break;
998 case Instruction::SPUT:
999 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -07001000 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -07001001 rlSrc[0]);
1002 } else {
buzbee76592632012-06-29 15:18:35 -07001003 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001004 }
1005 break;
1006 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -07001007 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -07001008 rlSrc[0]);
1009 break;
1010 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -07001011 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001012 break;
1013 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -07001014 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001015 break;
1016 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -07001017 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001018 break;
1019 case Instruction::SPUT_WIDE:
1020 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -07001021 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -07001022 rlSrc[0]);
1023 } else {
buzbee76592632012-06-29 15:18:35 -07001024 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -07001025 rlSrc[0]);
1026 }
1027 break;
1028
1029 case Instruction::SGET_OBJECT:
1030 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
1031 break;
1032 case Instruction::SGET:
1033 if (rlDest.fp) {
1034 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
1035 } else {
1036 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
1037 }
1038 break;
1039 case Instruction::SGET_BOOLEAN:
1040 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
1041 break;
1042 case Instruction::SGET_BYTE:
1043 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
1044 break;
1045 case Instruction::SGET_CHAR:
1046 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
1047 break;
1048 case Instruction::SGET_SHORT:
1049 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
1050 break;
1051 case Instruction::SGET_WIDE:
1052 if (rlDest.fp) {
1053 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
1054 rlDest);
1055 } else {
1056 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001057 }
1058 break;
buzbee2cfc6392012-05-07 14:51:40 -07001059
1060 case Instruction::RETURN_WIDE:
1061 case Instruction::RETURN:
1062 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -07001063 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001064 emitSuspendCheck(cUnit);
1065 }
buzbeeb03f4872012-06-11 15:22:11 -07001066 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001067 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
1068 bb->hasReturn = true;
1069 }
1070 break;
1071
1072 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001073 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001074 emitSuspendCheck(cUnit);
1075 }
buzbeeb03f4872012-06-11 15:22:11 -07001076 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001077 cUnit->irb->CreateRetVoid();
1078 bb->hasReturn = true;
1079 }
1080 break;
1081
1082 case Instruction::IF_EQ:
1083 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1084 break;
1085 case Instruction::IF_NE:
1086 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1087 break;
1088 case Instruction::IF_LT:
1089 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1090 break;
1091 case Instruction::IF_GE:
1092 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1093 break;
1094 case Instruction::IF_GT:
1095 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1096 break;
1097 case Instruction::IF_LE:
1098 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1099 break;
1100 case Instruction::IF_EQZ:
1101 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1102 break;
1103 case Instruction::IF_NEZ:
1104 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1105 break;
1106 case Instruction::IF_LTZ:
1107 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1108 break;
1109 case Instruction::IF_GEZ:
1110 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1111 break;
1112 case Instruction::IF_GTZ:
1113 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1114 break;
1115 case Instruction::IF_LEZ:
1116 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1117 break;
1118
1119 case Instruction::GOTO:
1120 case Instruction::GOTO_16:
1121 case Instruction::GOTO_32: {
1122 if (bb->taken->startOffset <= bb->startOffset) {
1123 emitSuspendCheck(cUnit);
1124 }
1125 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1126 }
1127 break;
1128
1129 case Instruction::ADD_LONG:
1130 case Instruction::ADD_LONG_2ADDR:
1131 case Instruction::ADD_INT:
1132 case Instruction::ADD_INT_2ADDR:
1133 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1134 break;
1135 case Instruction::SUB_LONG:
1136 case Instruction::SUB_LONG_2ADDR:
1137 case Instruction::SUB_INT:
1138 case Instruction::SUB_INT_2ADDR:
1139 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1140 break;
1141 case Instruction::MUL_LONG:
1142 case Instruction::MUL_LONG_2ADDR:
1143 case Instruction::MUL_INT:
1144 case Instruction::MUL_INT_2ADDR:
1145 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1146 break;
1147 case Instruction::DIV_LONG:
1148 case Instruction::DIV_LONG_2ADDR:
1149 case Instruction::DIV_INT:
1150 case Instruction::DIV_INT_2ADDR:
1151 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1152 break;
1153 case Instruction::REM_LONG:
1154 case Instruction::REM_LONG_2ADDR:
1155 case Instruction::REM_INT:
1156 case Instruction::REM_INT_2ADDR:
1157 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1158 break;
1159 case Instruction::AND_LONG:
1160 case Instruction::AND_LONG_2ADDR:
1161 case Instruction::AND_INT:
1162 case Instruction::AND_INT_2ADDR:
1163 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1164 break;
1165 case Instruction::OR_LONG:
1166 case Instruction::OR_LONG_2ADDR:
1167 case Instruction::OR_INT:
1168 case Instruction::OR_INT_2ADDR:
1169 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1170 break;
1171 case Instruction::XOR_LONG:
1172 case Instruction::XOR_LONG_2ADDR:
1173 case Instruction::XOR_INT:
1174 case Instruction::XOR_INT_2ADDR:
1175 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1176 break;
1177 case Instruction::SHL_LONG:
1178 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001179 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1180 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001181 break;
buzbee2cfc6392012-05-07 14:51:40 -07001182 case Instruction::SHL_INT:
1183 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001184 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1185 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001186 break;
1187 case Instruction::SHR_LONG:
1188 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001189 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1190 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001191 break;
buzbee2cfc6392012-05-07 14:51:40 -07001192 case Instruction::SHR_INT:
1193 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001194 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1195 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001196 break;
1197 case Instruction::USHR_LONG:
1198 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001199 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1200 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001201 break;
buzbee2cfc6392012-05-07 14:51:40 -07001202 case Instruction::USHR_INT:
1203 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001204 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1205 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001206 break;
1207
1208 case Instruction::ADD_INT_LIT16:
1209 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001210 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001211 break;
1212 case Instruction::RSUB_INT:
1213 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001214 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001215 break;
1216 case Instruction::MUL_INT_LIT16:
1217 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001218 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001219 break;
1220 case Instruction::DIV_INT_LIT16:
1221 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001222 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001223 break;
1224 case Instruction::REM_INT_LIT16:
1225 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001226 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001227 break;
1228 case Instruction::AND_INT_LIT16:
1229 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001230 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001231 break;
1232 case Instruction::OR_INT_LIT16:
1233 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001234 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001235 break;
1236 case Instruction::XOR_INT_LIT16:
1237 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001238 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001239 break;
1240 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001241 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1242 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001243 break;
1244 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001245 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1246 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001247 break;
1248 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001249 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1250 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001251 break;
1252
1253 case Instruction::ADD_FLOAT:
1254 case Instruction::ADD_FLOAT_2ADDR:
1255 case Instruction::ADD_DOUBLE:
1256 case Instruction::ADD_DOUBLE_2ADDR:
1257 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1258 break;
1259
1260 case Instruction::SUB_FLOAT:
1261 case Instruction::SUB_FLOAT_2ADDR:
1262 case Instruction::SUB_DOUBLE:
1263 case Instruction::SUB_DOUBLE_2ADDR:
1264 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1265 break;
1266
1267 case Instruction::MUL_FLOAT:
1268 case Instruction::MUL_FLOAT_2ADDR:
1269 case Instruction::MUL_DOUBLE:
1270 case Instruction::MUL_DOUBLE_2ADDR:
1271 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1272 break;
1273
1274 case Instruction::DIV_FLOAT:
1275 case Instruction::DIV_FLOAT_2ADDR:
1276 case Instruction::DIV_DOUBLE:
1277 case Instruction::DIV_DOUBLE_2ADDR:
1278 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1279 break;
1280
1281 case Instruction::REM_FLOAT:
1282 case Instruction::REM_FLOAT_2ADDR:
1283 case Instruction::REM_DOUBLE:
1284 case Instruction::REM_DOUBLE_2ADDR:
1285 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1286 break;
1287
buzbee6969d502012-06-15 16:40:31 -07001288 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001289 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1290 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001291 break;
1292 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001293 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1294 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001295 break;
1296
1297 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001298 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1299 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001300 break;
1301 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001302 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1303 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001304 break;
1305
1306 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001307 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1308 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001309 break;
1310 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001311 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1312 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001313 break;
1314
1315 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001316 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1317 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001318 break;
1319 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001320 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1321 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001322 break;
1323
1324 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001325 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1326 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001327 break;
1328 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001329 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1330 false /* NewFilledArray */);
1331 break;
1332 case Instruction::FILLED_NEW_ARRAY:
1333 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1334 true /* NewFilledArray */);
1335 break;
1336 case Instruction::FILLED_NEW_ARRAY_RANGE:
1337 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1338 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001339 break;
1340
1341 case Instruction::CONST_STRING:
1342 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001343 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1344 rlDest);
1345 break;
1346
1347 case Instruction::CONST_CLASS:
1348 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1349 rlDest);
1350 break;
1351
1352 case Instruction::CHECK_CAST:
1353 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001354 break;
1355
buzbee4f1181f2012-06-22 13:52:12 -07001356 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001357 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001358 break;
1359
buzbee32412962012-06-26 16:27:56 -07001360 case Instruction::MOVE_EXCEPTION:
1361 convertMoveException(cUnit, rlDest);
1362 break;
1363
1364 case Instruction::THROW:
1365 convertThrow(cUnit, rlSrc[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001366 /*
1367 * If this throw is standalone, terminate.
1368 * If it might rethrow, force termination
1369 * of the following block.
1370 */
1371 if (bb->fallThrough == NULL) {
1372 cUnit->irb->CreateUnreachable();
1373 } else {
1374 bb->fallThrough->fallThrough = NULL;
1375 bb->fallThrough->taken = NULL;
1376 }
buzbee32412962012-06-26 16:27:56 -07001377 break;
1378
buzbee2cfc6392012-05-07 14:51:40 -07001379 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001380 case Instruction::MOVE_RESULT:
1381 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001382 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001383 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001384 */
jeffhao9a4f0032012-08-30 16:17:40 -07001385 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001386 break;
1387
1388 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001389 convertMonitorEnterExit(cUnit, optFlags,
1390 greenland::IntrinsicHelper::MonitorEnter,
1391 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001392 break;
1393
1394 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001395 convertMonitorEnterExit(cUnit, optFlags,
1396 greenland::IntrinsicHelper::MonitorExit,
1397 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001398 break;
1399
1400 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001401 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001402 break;
1403
1404 case Instruction::NEW_ARRAY:
1405 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1406 break;
1407
1408 case Instruction::INSTANCE_OF:
1409 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1410 break;
1411
1412 case Instruction::AGET:
1413 if (rlDest.fp) {
1414 convertAget(cUnit, optFlags,
1415 greenland::IntrinsicHelper::HLArrayGetFloat,
1416 rlDest, rlSrc[0], rlSrc[1]);
1417 } else {
1418 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1419 rlDest, rlSrc[0], rlSrc[1]);
1420 }
1421 break;
1422 case Instruction::AGET_OBJECT:
1423 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1424 rlDest, rlSrc[0], rlSrc[1]);
1425 break;
1426 case Instruction::AGET_BOOLEAN:
1427 convertAget(cUnit, optFlags,
1428 greenland::IntrinsicHelper::HLArrayGetBoolean,
1429 rlDest, rlSrc[0], rlSrc[1]);
1430 break;
1431 case Instruction::AGET_BYTE:
1432 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1433 rlDest, rlSrc[0], rlSrc[1]);
1434 break;
1435 case Instruction::AGET_CHAR:
1436 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1437 rlDest, rlSrc[0], rlSrc[1]);
1438 break;
1439 case Instruction::AGET_SHORT:
1440 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1441 rlDest, rlSrc[0], rlSrc[1]);
1442 break;
1443 case Instruction::AGET_WIDE:
1444 if (rlDest.fp) {
1445 convertAget(cUnit, optFlags,
1446 greenland::IntrinsicHelper::HLArrayGetDouble,
1447 rlDest, rlSrc[0], rlSrc[1]);
1448 } else {
1449 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1450 rlDest, rlSrc[0], rlSrc[1]);
1451 }
1452 break;
1453
1454 case Instruction::APUT:
1455 if (rlSrc[0].fp) {
1456 convertAput(cUnit, optFlags,
1457 greenland::IntrinsicHelper::HLArrayPutFloat,
1458 rlSrc[0], rlSrc[1], rlSrc[2]);
1459 } else {
1460 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1461 rlSrc[0], rlSrc[1], rlSrc[2]);
1462 }
1463 break;
1464 case Instruction::APUT_OBJECT:
1465 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1466 rlSrc[0], rlSrc[1], rlSrc[2]);
1467 break;
1468 case Instruction::APUT_BOOLEAN:
1469 convertAput(cUnit, optFlags,
1470 greenland::IntrinsicHelper::HLArrayPutBoolean,
1471 rlSrc[0], rlSrc[1], rlSrc[2]);
1472 break;
1473 case Instruction::APUT_BYTE:
1474 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1475 rlSrc[0], rlSrc[1], rlSrc[2]);
1476 break;
1477 case Instruction::APUT_CHAR:
1478 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1479 rlSrc[0], rlSrc[1], rlSrc[2]);
1480 break;
1481 case Instruction::APUT_SHORT:
1482 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1483 rlSrc[0], rlSrc[1], rlSrc[2]);
1484 break;
1485 case Instruction::APUT_WIDE:
1486 if (rlSrc[0].fp) {
1487 convertAput(cUnit, optFlags,
1488 greenland::IntrinsicHelper::HLArrayPutDouble,
1489 rlSrc[0], rlSrc[1], rlSrc[2]);
1490 } else {
1491 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1492 rlSrc[0], rlSrc[1], rlSrc[2]);
1493 }
1494 break;
1495
buzbee101305f2012-06-28 18:00:56 -07001496 case Instruction::IGET:
1497 if (rlDest.fp) {
1498 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001499 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001500 } else {
1501 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001502 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001503 }
buzbee2cfc6392012-05-07 14:51:40 -07001504 break;
buzbee101305f2012-06-28 18:00:56 -07001505 case Instruction::IGET_OBJECT:
1506 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001507 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001508 break;
1509 case Instruction::IGET_BOOLEAN:
1510 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001511 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001512 break;
1513 case Instruction::IGET_BYTE:
1514 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001515 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001516 break;
1517 case Instruction::IGET_CHAR:
1518 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001519 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001520 break;
1521 case Instruction::IGET_SHORT:
1522 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001523 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001524 break;
1525 case Instruction::IGET_WIDE:
1526 if (rlDest.fp) {
1527 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001528 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001529 } else {
1530 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001531 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001532 }
1533 break;
1534 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001535 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001536 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1537 rlSrc[0], rlSrc[1], vC);
1538 } else {
1539 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1540 rlSrc[0], rlSrc[1], vC);
1541 }
1542 break;
1543 case Instruction::IPUT_OBJECT:
1544 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1545 rlSrc[0], rlSrc[1], vC);
1546 break;
1547 case Instruction::IPUT_BOOLEAN:
1548 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1549 rlSrc[0], rlSrc[1], vC);
1550 break;
1551 case Instruction::IPUT_BYTE:
1552 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1553 rlSrc[0], rlSrc[1], vC);
1554 break;
1555 case Instruction::IPUT_CHAR:
1556 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1557 rlSrc[0], rlSrc[1], vC);
1558 break;
1559 case Instruction::IPUT_SHORT:
1560 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1561 rlSrc[0], rlSrc[1], vC);
1562 break;
1563 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001564 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001565 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1566 rlSrc[0], rlSrc[1], vC);
1567 } else {
1568 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1569 rlSrc[0], rlSrc[1], vC);
1570 }
buzbee2cfc6392012-05-07 14:51:40 -07001571 break;
1572
1573 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001574 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001575 break;
1576
buzbee76592632012-06-29 15:18:35 -07001577 case Instruction::LONG_TO_INT:
1578 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1579 break;
1580
buzbee101305f2012-06-28 18:00:56 -07001581 case Instruction::INT_TO_LONG:
1582 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001583 break;
1584
buzbee101305f2012-06-28 18:00:56 -07001585 case Instruction::INT_TO_CHAR:
1586 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1587 greenland::IntrinsicHelper::IntToChar);
1588 break;
1589 case Instruction::INT_TO_BYTE:
1590 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1591 greenland::IntrinsicHelper::IntToByte);
1592 break;
1593 case Instruction::INT_TO_SHORT:
1594 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1595 greenland::IntrinsicHelper::IntToShort);
1596 break;
1597
buzbee76592632012-06-29 15:18:35 -07001598 case Instruction::INT_TO_FLOAT:
1599 case Instruction::LONG_TO_FLOAT:
1600 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001601 break;
1602
buzbee76592632012-06-29 15:18:35 -07001603 case Instruction::INT_TO_DOUBLE:
1604 case Instruction::LONG_TO_DOUBLE:
1605 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001606 break;
1607
buzbee76592632012-06-29 15:18:35 -07001608 case Instruction::FLOAT_TO_DOUBLE:
1609 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001610 break;
1611
buzbee76592632012-06-29 15:18:35 -07001612 case Instruction::DOUBLE_TO_FLOAT:
1613 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001614 break;
1615
1616 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001617 case Instruction::NEG_INT:
1618 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001619 break;
1620
1621 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001622 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001623 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001624 break;
1625
buzbee76592632012-06-29 15:18:35 -07001626 case Instruction::NOT_LONG:
1627 case Instruction::NOT_INT:
1628 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001629 break;
1630
buzbee2cfc6392012-05-07 14:51:40 -07001631 case Instruction::FLOAT_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001632 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2I, rlDest, rlSrc[0]);
1633 break;
1634
buzbee2cfc6392012-05-07 14:51:40 -07001635 case Instruction::DOUBLE_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001636 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2I, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001637 break;
1638
buzbee76592632012-06-29 15:18:35 -07001639 case Instruction::FLOAT_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001640 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2L, rlDest, rlSrc[0]);
1641 break;
1642
buzbee76592632012-06-29 15:18:35 -07001643 case Instruction::DOUBLE_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001644 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2L, rlDest, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001645 break;
1646
1647 case Instruction::CMPL_FLOAT:
1648 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1649 rlDest, rlSrc[0], rlSrc[1]);
1650 break;
1651 case Instruction::CMPG_FLOAT:
1652 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1653 rlDest, rlSrc[0], rlSrc[1]);
1654 break;
1655 case Instruction::CMPL_DOUBLE:
1656 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1657 rlDest, rlSrc[0], rlSrc[1]);
1658 break;
1659 case Instruction::CMPG_DOUBLE:
1660 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1661 rlDest, rlSrc[0], rlSrc[1]);
1662 break;
1663 case Instruction::CMP_LONG:
1664 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1665 rlDest, rlSrc[0], rlSrc[1]);
1666 break;
1667
buzbee76592632012-06-29 15:18:35 -07001668 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001669 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001670 break;
1671
1672 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001673 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001674 break;
buzbee2cfc6392012-05-07 14:51:40 -07001675
1676 default:
buzbee32412962012-06-26 16:27:56 -07001677 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001678 res = true;
1679 }
buzbeeb03f4872012-06-11 15:22:11 -07001680 if (objectDefinition) {
buzbeecbd6d442012-11-17 14:11:25 -08001681 setShadowFrameEntry(cUnit, reinterpret_cast<llvm::Value*>
1682 (cUnit->llvmValues.elemList[rlDest.origSReg]));
buzbeeb03f4872012-06-11 15:22:11 -07001683 }
buzbee2cfc6392012-05-07 14:51:40 -07001684 return res;
1685}
1686
1687/* Extended MIR instructions like PHI */
1688void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1689 llvm::BasicBlock* llvmBB)
1690{
1691
buzbeecbd6d442012-11-17 14:11:25 -08001692 switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
buzbee2cfc6392012-05-07 14:51:40 -07001693 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001694 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001695 /*
1696 * The Art compiler's Phi nodes only handle 32-bit operands,
1697 * representing wide values using a matched set of Phi nodes
1698 * for the lower and upper halves. In the llvm world, we only
1699 * want a single Phi for wides. Here we will simply discard
1700 * the Phi node representing the high word.
1701 */
1702 if (rlDest.highWord) {
1703 return; // No Phi node - handled via low word
1704 }
buzbeecbd6d442012-11-17 14:11:25 -08001705 int* incoming = reinterpret_cast<int*>(mir->dalvikInsn.vB);
buzbee2cfc6392012-05-07 14:51:40 -07001706 llvm::Type* phiType =
1707 llvmTypeFromLocRec(cUnit, rlDest);
1708 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1709 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1710 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001711 // Don't check width here.
1712 loc = oatGetRawSrc(cUnit, mir, i);
1713 DCHECK_EQ(rlDest.wide, loc.wide);
1714 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1715 DCHECK_EQ(rlDest.fp, loc.fp);
1716 DCHECK_EQ(rlDest.core, loc.core);
1717 DCHECK_EQ(rlDest.ref, loc.ref);
buzbeed1643e42012-09-05 14:06:51 -07001718 SafeMap<unsigned int, unsigned int>::iterator it;
1719 it = cUnit->blockIdMap.find(incoming[i]);
1720 DCHECK(it != cUnit->blockIdMap.end());
buzbee2cfc6392012-05-07 14:51:40 -07001721 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
buzbeed1643e42012-09-05 14:06:51 -07001722 getLLVMBlock(cUnit, it->second));
buzbee2cfc6392012-05-07 14:51:40 -07001723 }
1724 defineValue(cUnit, phi, rlDest.origSReg);
1725 break;
1726 }
1727 case kMirOpCopy: {
1728 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1729 break;
1730 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001731 case kMirOpNop:
1732 if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
1733 (bb->fallThrough == NULL)) {
1734 cUnit->irb->CreateUnreachable();
1735 }
1736 break;
1737
buzbeeb046e162012-10-30 15:48:42 -07001738 // TODO: need GBC intrinsic to take advantage of fused operations
buzbee2cfc6392012-05-07 14:51:40 -07001739 case kMirOpFusedCmplFloat:
buzbeeb046e162012-10-30 15:48:42 -07001740 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpFloat unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001741 break;
1742 case kMirOpFusedCmpgFloat:
buzbeeb046e162012-10-30 15:48:42 -07001743 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmgFloat unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001744 break;
1745 case kMirOpFusedCmplDouble:
buzbeeb046e162012-10-30 15:48:42 -07001746 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmplDouble unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001747 break;
1748 case kMirOpFusedCmpgDouble:
buzbeeb046e162012-10-30 15:48:42 -07001749 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpgDouble unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001750 break;
1751 case kMirOpFusedCmpLong:
buzbeeb046e162012-10-30 15:48:42 -07001752 UNIMPLEMENTED(FATAL) << "kMirOpLongCmpBranch unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001753 break;
buzbee2cfc6392012-05-07 14:51:40 -07001754 default:
1755 break;
1756 }
1757}
1758
1759void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1760{
1761 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001762 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001763 arrayRef.push_back(cUnit->irb->getInt32(offset));
1764 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1765 cUnit->irb->SetDexOffset(node);
1766}
1767
1768// Attach method info as metadata to special intrinsic
1769void setMethodInfo(CompilationUnit* cUnit)
1770{
1771 // We don't want dex offset on this
1772 cUnit->irb->SetDexOffset(NULL);
1773 greenland::IntrinsicHelper::IntrinsicId id;
1774 id = greenland::IntrinsicHelper::MethodInfo;
1775 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1776 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1777 llvm::SmallVector<llvm::Value*, 2> regInfo;
1778 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1779 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1780 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1781 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1782 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1783 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1784 inst->setMetadata("RegInfo", regInfoNode);
1785 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1786 llvm::SmallVector<llvm::Value*, 50> pmap;
1787 for (int i = 0; i < promoSize; i++) {
1788 PromotionMap* p = &cUnit->promotionMap[i];
1789 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1790 ((p->fpReg & 0xff) << 16) |
1791 ((p->coreReg & 0xff) << 8) |
1792 ((p->fpLocation & 0xf) << 4) |
1793 (p->coreLocation & 0xf);
1794 pmap.push_back(cUnit->irb->getInt32(mapData));
1795 }
1796 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1797 inst->setMetadata("PromotionMap", mapNode);
1798 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1799}
1800
1801/* Handle the content in each basic block */
1802bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1803{
buzbeed1643e42012-09-05 14:06:51 -07001804 if (bb->blockType == kDead) return false;
buzbee2cfc6392012-05-07 14:51:40 -07001805 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
buzbeef5f5a122012-09-21 13:57:36 -07001806 if (llvmBB == NULL) {
1807 CHECK(bb->blockType == kExitBlock);
1808 } else {
1809 cUnit->irb->SetInsertPoint(llvmBB);
1810 setDexOffset(cUnit, bb->startOffset);
1811 }
buzbee2cfc6392012-05-07 14:51:40 -07001812
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001813 if (cUnit->printMe) {
1814 LOG(INFO) << "................................";
1815 LOG(INFO) << "Block id " << bb->id;
1816 if (llvmBB != NULL) {
1817 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1818 } else {
1819 LOG(INFO) << "llvmBB is NULL";
1820 }
1821 }
1822
buzbee2cfc6392012-05-07 14:51:40 -07001823 if (bb->blockType == kEntryBlock) {
1824 setMethodInfo(cUnit);
buzbeecbd6d442012-11-17 14:11:25 -08001825 bool *canBeRef = static_cast<bool*>(oatNew(cUnit, sizeof(bool) * cUnit->numDalvikRegisters,
1826 true, kAllocMisc));
buzbeeb03f4872012-06-11 15:22:11 -07001827 for (int i = 0; i < cUnit->numSSARegs; i++) {
buzbee6ec5e232012-09-20 15:50:03 -07001828 int vReg = SRegToVReg(cUnit, i);
1829 if (vReg > SSA_METHOD_BASEREG) {
1830 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1831 }
buzbeeb03f4872012-06-11 15:22:11 -07001832 }
1833 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1834 if (canBeRef[i]) {
1835 cUnit->numShadowFrameEntries++;
1836 }
1837 }
1838 if (cUnit->numShadowFrameEntries > 0) {
buzbeecbd6d442012-11-17 14:11:25 -08001839 cUnit->shadowMap = static_cast<int*>(oatNew(cUnit, sizeof(int) * cUnit->numShadowFrameEntries,
1840 true, kAllocMisc));
buzbeeb03f4872012-06-11 15:22:11 -07001841 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1842 if (canBeRef[i]) {
1843 cUnit->shadowMap[j++] = i;
1844 }
1845 }
buzbeeb03f4872012-06-11 15:22:11 -07001846 }
Shih-wei Liao569daf12012-08-10 23:22:33 -07001847 greenland::IntrinsicHelper::IntrinsicId id =
1848 greenland::IntrinsicHelper::AllocaShadowFrame;
1849 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1850 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
TDYa1278e950c12012-11-02 09:58:19 -07001851 llvm::Value* dalvikRegs = cUnit->irb->getInt32(cUnit->numDalvikRegisters);
1852 llvm::Value* args[] = { entries, dalvikRegs };
1853 cUnit->irb->CreateCall(func, args);
buzbee2cfc6392012-05-07 14:51:40 -07001854 } else if (bb->blockType == kExitBlock) {
1855 /*
1856 * Because of the differences between how MIR/LIR and llvm handle exit
1857 * blocks, we won't explicitly covert them. On the llvm-to-lir
1858 * path, it will need to be regenereated.
1859 */
1860 return false;
buzbee6969d502012-06-15 16:40:31 -07001861 } else if (bb->blockType == kExceptionHandling) {
1862 /*
1863 * Because we're deferring null checking, delete the associated empty
1864 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001865 */
1866 llvmBB->eraseFromParent();
1867 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001868 }
1869
1870 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1871
1872 setDexOffset(cUnit, mir->offset);
1873
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001874 int opcode = mir->dalvikInsn.opcode;
1875 Instruction::Format dalvikFormat =
1876 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001877
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001878 if (opcode == kMirOpCheck) {
1879 // Combine check and work halves of throwing instruction.
1880 MIR* workHalf = mir->meta.throwInsn;
1881 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
1882 opcode = mir->dalvikInsn.opcode;
1883 SSARepresentation* ssaRep = workHalf->ssaRep;
1884 workHalf->ssaRep = mir->ssaRep;
1885 mir->ssaRep = ssaRep;
1886 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1887 if (bb->successorBlockList.blockListType == kCatch) {
1888 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
1889 greenland::IntrinsicHelper::CatchTargets);
1890 llvm::Value* switchKey =
1891 cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
1892 GrowableListIterator iter;
1893 oatGrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
1894 // New basic block to use for work half
1895 llvm::BasicBlock* workBB =
1896 llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
1897 llvm::SwitchInst* sw =
1898 cUnit->irb->CreateSwitch(switchKey, workBB,
1899 bb->successorBlockList.blocks.numUsed);
1900 while (true) {
1901 SuccessorBlockInfo *successorBlockInfo =
buzbeecbd6d442012-11-17 14:11:25 -08001902 reinterpret_cast<SuccessorBlockInfo*>(oatGrowableListIteratorNext(&iter));
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001903 if (successorBlockInfo == NULL) break;
1904 llvm::BasicBlock *target =
1905 getLLVMBlock(cUnit, successorBlockInfo->block->id);
1906 int typeIndex = successorBlockInfo->key;
1907 sw->addCase(cUnit->irb->getInt32(typeIndex), target);
1908 }
1909 llvmBB = workBB;
1910 cUnit->irb->SetInsertPoint(llvmBB);
1911 }
1912 }
1913
1914 if (opcode >= kMirOpFirst) {
buzbee2cfc6392012-05-07 14:51:40 -07001915 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1916 continue;
1917 }
1918
1919 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1920 NULL /* labelList */);
1921 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001922 Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001923 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001924 mir->offset, opcode,
buzbee2cfc6392012-05-07 14:51:40 -07001925 Instruction::Name(dalvikOpcode),
1926 dalvikFormat);
1927 }
1928 }
1929
buzbee4be777b2012-07-12 14:38:18 -07001930 if (bb->blockType == kEntryBlock) {
1931 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1932 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001933 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1934 }
1935
1936 return false;
1937}
1938
buzbee4f4dfc72012-07-02 14:54:44 -07001939char remapShorty(char shortyType) {
1940 /*
1941 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1942 * and longs/doubles are represented as a pair of registers. When sub-word
1943 * arguments (and method results) are passed, they are extended to Dalvik
1944 * virtual register containers. Because llvm is picky about type consistency,
1945 * we must either cast the "real" type to 32-bit container multiple Dalvik
1946 * register types, or always use the expanded values.
1947 * Here, we're doing the latter. We map the shorty signature to container
1948 * types (which is valid so long as we always do a real expansion of passed
1949 * arguments and field loads).
1950 */
1951 switch(shortyType) {
1952 case 'Z' : shortyType = 'I'; break;
1953 case 'B' : shortyType = 'I'; break;
1954 case 'S' : shortyType = 'I'; break;
1955 case 'C' : shortyType = 'I'; break;
1956 default: break;
1957 }
1958 return shortyType;
1959}
1960
buzbee2cfc6392012-05-07 14:51:40 -07001961llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1962
1963 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001964 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001965 greenland::kAccurate);
1966
1967 // Get argument type
1968 std::vector<llvm::Type*> args_type;
1969
1970 // method object
1971 args_type.push_back(cUnit->irb->GetJMethodTy());
1972
1973 // Do we have a "this"?
1974 if ((cUnit->access_flags & kAccStatic) == 0) {
1975 args_type.push_back(cUnit->irb->GetJObjectTy());
1976 }
1977
1978 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001979 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001980 greenland::kAccurate));
1981 }
1982
1983 return llvm::FunctionType::get(ret_type, args_type, false);
1984}
1985
1986bool createFunction(CompilationUnit* cUnit) {
1987 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1988 /* with_signature */ false));
1989 llvm::FunctionType* func_type = getFunctionType(cUnit);
1990
1991 if (func_type == NULL) {
1992 return false;
1993 }
1994
1995 cUnit->func = llvm::Function::Create(func_type,
1996 llvm::Function::ExternalLinkage,
1997 func_name, cUnit->module);
1998
1999 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2000 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
2001
2002 arg_iter->setName("method");
2003 ++arg_iter;
2004
2005 int startSReg = cUnit->numRegs;
2006
2007 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
2008 arg_iter->setName(StringPrintf("v%i_0", startSReg));
2009 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
2010 }
2011
2012 return true;
2013}
2014
2015bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
2016{
2017 // Skip the exit block
buzbeed1643e42012-09-05 14:06:51 -07002018 if ((bb->blockType == kDead) ||(bb->blockType == kExitBlock)) {
buzbee2cfc6392012-05-07 14:51:40 -07002019 cUnit->idToBlockMap.Put(bb->id, NULL);
2020 } else {
2021 int offset = bb->startOffset;
2022 bool entryBlock = (bb->blockType == kEntryBlock);
2023 llvm::BasicBlock* llvmBB =
2024 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
buzbee8320f382012-09-11 16:29:42 -07002025 StringPrintf(kLabelFormat, bb->catchEntry ? kCatchBlock :
2026 kNormalBlock, offset, bb->id), cUnit->func);
buzbee2cfc6392012-05-07 14:51:40 -07002027 if (entryBlock) {
2028 cUnit->entryBB = llvmBB;
2029 cUnit->placeholderBB =
2030 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
2031 cUnit->func);
2032 }
2033 cUnit->idToBlockMap.Put(bb->id, llvmBB);
2034 }
2035 return false;
2036}
2037
2038
2039/*
2040 * Convert MIR to LLVM_IR
2041 * o For each ssa name, create LLVM named value. Type these
2042 * appropriately, and ignore high half of wide and double operands.
2043 * o For each MIR basic block, create an LLVM basic block.
2044 * o Iterate through the MIR a basic block at a time, setting arguments
2045 * to recovered ssa name.
2046 */
2047void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
2048{
2049 initIR(cUnit);
2050 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
2051
2052 // Create the function
2053 createFunction(cUnit);
2054
2055 // Create an LLVM basic block for each MIR block in dfs preorder
2056 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
2057 kPreOrderDFSTraversal, false /* isIterative */);
2058 /*
2059 * Create an llvm named value for each MIR SSA name. Note: we'll use
2060 * placeholders for all non-argument values (because we haven't seen
2061 * the definition yet).
2062 */
2063 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2064 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2065 arg_iter++; /* Skip path method */
2066 for (int i = 0; i < cUnit->numSSARegs; i++) {
2067 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07002068 RegLocation rlTemp = cUnit->regLocation[i];
2069 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07002070 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
2071 } else if ((i < cUnit->numRegs) ||
2072 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07002073 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
2074 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07002075 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
2076 val->setName(llvmSSAName(cUnit, i));
buzbeecbd6d442012-11-17 14:11:25 -08002077 oatInsertGrowableList(cUnit, &cUnit->llvmValues, reinterpret_cast<uintptr_t>(val));
buzbee2cfc6392012-05-07 14:51:40 -07002078 } else {
2079 // Recover previously-created argument values
2080 llvm::Value* argVal = arg_iter++;
buzbeecbd6d442012-11-17 14:11:25 -08002081 oatInsertGrowableList(cUnit, &cUnit->llvmValues, reinterpret_cast<uintptr_t>(argVal));
buzbee2cfc6392012-05-07 14:51:40 -07002082 }
2083 }
buzbee2cfc6392012-05-07 14:51:40 -07002084
2085 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
2086 kPreOrderDFSTraversal, false /* Iterative */);
2087
buzbee4be777b2012-07-12 14:38:18 -07002088 /*
2089 * In a few rare cases of verification failure, the verifier will
2090 * replace one or more Dalvik opcodes with the special
2091 * throw-verification-failure opcode. This can leave the SSA graph
2092 * in an invalid state, as definitions may be lost, while uses retained.
2093 * To work around this problem, we insert placeholder definitions for
2094 * all Dalvik SSA regs in the "placeholder" block. Here, after
2095 * bitcode conversion is complete, we examine those placeholder definitions
2096 * and delete any with no references (which normally is all of them).
2097 *
2098 * If any definitions remain, we link the placeholder block into the
2099 * CFG. Otherwise, it is deleted.
2100 */
2101 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
2102 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
2103 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2104 DCHECK(inst != NULL);
2105 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2106 DCHECK(val != NULL);
2107 if (val->getNumUses() == 0) {
2108 inst->eraseFromParent();
2109 }
2110 }
2111 setDexOffset(cUnit, 0);
2112 if (cUnit->placeholderBB->empty()) {
2113 cUnit->placeholderBB->eraseFromParent();
2114 } else {
2115 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2116 cUnit->irb->CreateBr(cUnit->entryTargetBB);
2117 cUnit->entryTargetBB = cUnit->placeholderBB;
2118 }
2119 cUnit->irb->SetInsertPoint(cUnit->entryBB);
2120 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07002121
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002122 if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
2123 if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
2124 LOG(INFO) << "Bitcode verification FAILED for "
2125 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
2126 << " of size " << cUnit->insnsSize;
2127 cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
2128 }
2129 }
buzbee2cfc6392012-05-07 14:51:40 -07002130
buzbeead8f15e2012-06-18 14:49:45 -07002131 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
2132 // Write bitcode to file
2133 std::string errmsg;
2134 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
2135 oatReplaceSpecialChars(fname);
buzbee6459e7c2012-10-02 14:42:41 -07002136 // TODO: make configurable change naming mechanism to avoid fname length issues.
buzbee4f1181f2012-06-22 13:52:12 -07002137 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002138
buzbee6459e7c2012-10-02 14:42:41 -07002139 if (fname.size() > 240) {
2140 LOG(INFO) << "Warning: bitcode filename too long. Truncated.";
2141 fname.resize(240);
2142 }
2143
buzbeead8f15e2012-06-18 14:49:45 -07002144 llvm::OwningPtr<llvm::tool_output_file> out_file(
2145 new llvm::tool_output_file(fname.c_str(), errmsg,
2146 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002147
buzbeead8f15e2012-06-18 14:49:45 -07002148 if (!errmsg.empty()) {
2149 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2150 }
2151
2152 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2153 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002154 }
buzbee2cfc6392012-05-07 14:51:40 -07002155}
2156
2157RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2158 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002159 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002160 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2161 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002162 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002163 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002164 // FIXME: need to be more robust, handle FP and be in a position to
2165 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002166 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2167 memset(&res, 0, sizeof(res));
2168 res.location = kLocPhysReg;
2169 res.lowReg = oatAllocTemp(cUnit);
2170 res.home = true;
2171 res.sRegLow = INVALID_SREG;
2172 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002173 llvm::Type* ty = val->getType();
2174 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2175 (ty == cUnit->irb->getDoubleTy()));
2176 if (res.wide) {
2177 res.highReg = oatAllocTemp(cUnit);
2178 }
buzbee4f1181f2012-06-22 13:52:12 -07002179 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002180 } else {
2181 DCHECK_EQ(valName[0], 'v');
2182 int baseSReg = INVALID_SREG;
2183 sscanf(valName.c_str(), "v%d_", &baseSReg);
2184 res = cUnit->regLocation[baseSReg];
2185 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002186 }
2187 } else {
2188 res = it->second;
2189 }
2190 return res;
2191}
2192
2193Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2194{
2195 Instruction::Code res = Instruction::NOP;
2196 if (isWide) {
2197 switch(op) {
2198 case kOpAdd: res = Instruction::ADD_LONG; break;
2199 case kOpSub: res = Instruction::SUB_LONG; break;
2200 case kOpMul: res = Instruction::MUL_LONG; break;
2201 case kOpDiv: res = Instruction::DIV_LONG; break;
2202 case kOpRem: res = Instruction::REM_LONG; break;
2203 case kOpAnd: res = Instruction::AND_LONG; break;
2204 case kOpOr: res = Instruction::OR_LONG; break;
2205 case kOpXor: res = Instruction::XOR_LONG; break;
2206 case kOpLsl: res = Instruction::SHL_LONG; break;
2207 case kOpLsr: res = Instruction::USHR_LONG; break;
2208 case kOpAsr: res = Instruction::SHR_LONG; break;
2209 default: LOG(FATAL) << "Unexpected OpKind " << op;
2210 }
2211 } else if (isConst){
2212 switch(op) {
2213 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2214 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2215 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2216 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2217 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2218 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2219 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2220 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2221 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2222 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2223 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2224 default: LOG(FATAL) << "Unexpected OpKind " << op;
2225 }
2226 } else {
2227 switch(op) {
2228 case kOpAdd: res = Instruction::ADD_INT; break;
2229 case kOpSub: res = Instruction::SUB_INT; break;
2230 case kOpMul: res = Instruction::MUL_INT; break;
2231 case kOpDiv: res = Instruction::DIV_INT; break;
2232 case kOpRem: res = Instruction::REM_INT; break;
2233 case kOpAnd: res = Instruction::AND_INT; break;
2234 case kOpOr: res = Instruction::OR_INT; break;
2235 case kOpXor: res = Instruction::XOR_INT; break;
2236 case kOpLsl: res = Instruction::SHL_INT; break;
2237 case kOpLsr: res = Instruction::USHR_INT; break;
2238 case kOpAsr: res = Instruction::SHR_INT; break;
2239 default: LOG(FATAL) << "Unexpected OpKind " << op;
2240 }
2241 }
2242 return res;
2243}
2244
buzbee4f1181f2012-06-22 13:52:12 -07002245Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2246{
2247 Instruction::Code res = Instruction::NOP;
2248 if (isWide) {
2249 switch(op) {
2250 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2251 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2252 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2253 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2254 case kOpRem: res = Instruction::REM_DOUBLE; break;
2255 default: LOG(FATAL) << "Unexpected OpKind " << op;
2256 }
2257 } else {
2258 switch(op) {
2259 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2260 case kOpSub: res = Instruction::SUB_FLOAT; break;
2261 case kOpMul: res = Instruction::MUL_FLOAT; break;
2262 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2263 case kOpRem: res = Instruction::REM_FLOAT; break;
2264 default: LOG(FATAL) << "Unexpected OpKind " << op;
2265 }
2266 }
2267 return res;
2268}
2269
2270void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2271{
2272 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002273 /*
2274 * Normally, we won't ever generate an FP operation with an immediate
2275 * operand (not supported in Dex instruction set). However, the IR builder
2276 * may insert them - in particular for createNegFP. Recognize this case
2277 * and deal with it.
2278 */
2279 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2280 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2281 DCHECK(op2C == NULL);
2282 if ((op1C != NULL) && (op == kOpSub)) {
2283 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2284 if (rlDest.wide) {
2285 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2286 } else {
2287 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2288 }
buzbee4f1181f2012-06-22 13:52:12 -07002289 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002290 DCHECK(op1C == NULL);
2291 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2292 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2293 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2294 if (rlDest.wide) {
2295 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2296 } else {
2297 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2298 }
buzbee4f1181f2012-06-22 13:52:12 -07002299 }
2300}
2301
buzbee101305f2012-06-28 18:00:56 -07002302void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2303 Instruction::Code opcode)
2304{
2305 RegLocation rlDest = getLoc(cUnit, inst);
2306 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2307 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2308}
2309
buzbee76592632012-06-29 15:18:35 -07002310void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2311{
2312 RegLocation rlDest = getLoc(cUnit, inst);
2313 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2314 Instruction::Code opcode;
2315 if (rlDest.wide) {
2316 if (rlSrc.wide) {
2317 opcode = Instruction::LONG_TO_DOUBLE;
2318 } else {
2319 opcode = Instruction::INT_TO_DOUBLE;
2320 }
2321 } else {
2322 if (rlSrc.wide) {
2323 opcode = Instruction::LONG_TO_FLOAT;
2324 } else {
2325 opcode = Instruction::INT_TO_FLOAT;
2326 }
2327 }
2328 genConversion(cUnit, opcode, rlDest, rlSrc);
2329}
2330
TDYa1274ec8ccd2012-08-11 07:04:57 -07002331void cvtFPToInt(CompilationUnit* cUnit, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002332{
TDYa1274ec8ccd2012-08-11 07:04:57 -07002333 RegLocation rlDest = getLoc(cUnit, call_inst);
2334 RegLocation rlSrc = getLoc(cUnit, call_inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002335 Instruction::Code opcode;
2336 if (rlDest.wide) {
2337 if (rlSrc.wide) {
2338 opcode = Instruction::DOUBLE_TO_LONG;
2339 } else {
2340 opcode = Instruction::FLOAT_TO_LONG;
2341 }
2342 } else {
2343 if (rlSrc.wide) {
2344 opcode = Instruction::DOUBLE_TO_INT;
2345 } else {
2346 opcode = Instruction::FLOAT_TO_INT;
2347 }
2348 }
2349 genConversion(cUnit, opcode, rlDest, rlSrc);
2350}
2351
2352void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2353{
2354 RegLocation rlDest = getLoc(cUnit, inst);
2355 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2356 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2357}
2358
2359void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2360{
2361 RegLocation rlDest = getLoc(cUnit, inst);
2362 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2363 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2364 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2365 storeValue(cUnit, rlDest, rlSrc);
2366}
2367
2368void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2369{
2370 RegLocation rlDest = getLoc(cUnit, inst);
2371 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2372 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2373}
2374
2375
buzbee101305f2012-06-28 18:00:56 -07002376void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2377{
2378 // TODO: evaluate src/tgt types and add general support for more than int to long
2379 RegLocation rlDest = getLoc(cUnit, inst);
2380 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2381 DCHECK(rlDest.wide);
2382 DCHECK(!rlSrc.wide);
2383 DCHECK(!rlDest.fp);
2384 DCHECK(!rlSrc.fp);
2385 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2386 if (rlSrc.location == kLocPhysReg) {
2387 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2388 } else {
2389 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2390 }
2391 if (isSigned) {
2392 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2393 } else {
2394 loadConstant(cUnit, rlResult.highReg, 0);
2395 }
2396 storeValueWide(cUnit, rlDest, rlResult);
2397}
2398
buzbee2cfc6392012-05-07 14:51:40 -07002399void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2400{
2401 RegLocation rlDest = getLoc(cUnit, inst);
2402 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002403 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002404 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2405 if ((op == kOpSub) && (lhsImm != NULL)) {
2406 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002407 if (rlSrc1.wide) {
2408 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2409 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2410 } else {
2411 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2412 lhsImm->getSExtValue());
2413 }
buzbee4f1181f2012-06-22 13:52:12 -07002414 return;
2415 }
2416 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002417 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2418 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002419 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2420 if (!rlDest.wide && (constRhs != NULL)) {
buzbee2cfc6392012-05-07 14:51:40 -07002421 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
buzbee9a2487f2012-07-26 14:01:13 -07002422 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002423 } else {
2424 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002425 RegLocation rlSrc2;
2426 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002427 // ir_builder converts NOT_LONG to xor src, -1. Restore
2428 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2429 DCHECK_EQ(-1L, constRhs->getSExtValue());
2430 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002431 rlSrc2 = rlSrc1;
2432 } else {
2433 rlSrc2 = getLoc(cUnit, rhs);
2434 }
buzbee2cfc6392012-05-07 14:51:40 -07002435 if (rlDest.wide) {
2436 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2437 } else {
2438 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2439 }
2440 }
2441}
2442
buzbee2a83e8f2012-07-13 16:42:30 -07002443void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2444 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002445{
buzbee2a83e8f2012-07-13 16:42:30 -07002446 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2447 RegLocation rlDest = getLoc(cUnit, callInst);
2448 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2449 llvm::Value* rhs = callInst->getArgOperand(1);
2450 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2451 DCHECK(!rlDest.wide);
2452 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002453 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002454 RegLocation rlShift = getLoc(cUnit, rhs);
2455 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2456 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2457 } else {
2458 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2459 }
buzbee101305f2012-06-28 18:00:56 -07002460 }
2461}
2462
buzbee2cfc6392012-05-07 14:51:40 -07002463void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2464{
2465 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2466 DCHECK(brInst != NULL);
2467 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2468 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2469 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2470}
2471
2472void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2473{
2474 // Nop - these have already been processed
2475}
2476
2477void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2478{
2479 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2480 llvm::Value* retVal = retInst->getReturnValue();
2481 if (retVal != NULL) {
2482 RegLocation rlSrc = getLoc(cUnit, retVal);
2483 if (rlSrc.wide) {
2484 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2485 } else {
2486 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2487 }
2488 }
2489 genExitSequence(cUnit);
2490}
2491
2492ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2493{
2494 ConditionCode res = kCondAl;
2495 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002496 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002497 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2498 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2499 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002500 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002501 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002502 default: LOG(FATAL) << "Unexpected llvm condition";
2503 }
2504 return res;
2505}
2506
2507void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2508{
2509 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2510 UNIMPLEMENTED(FATAL);
2511}
2512
2513void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2514 llvm::BranchInst* brInst)
2515{
2516 // Get targets
2517 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2518 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2519 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2520 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2521 // Get comparison operands
2522 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2523 ConditionCode cond = getCond(iCmpInst->getPredicate());
2524 llvm::Value* lhs = iCmpInst->getOperand(0);
2525 // Not expecting a constant as 1st operand
2526 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2527 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2528 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2529 llvm::Value* rhs = inst->getOperand(1);
buzbeeb046e162012-10-30 15:48:42 -07002530 if (cUnit->instructionSet == kMips) {
2531 // Compare and branch in one shot
2532 UNIMPLEMENTED(FATAL);
2533 }
buzbee2cfc6392012-05-07 14:51:40 -07002534 //Compare, then branch
2535 // TODO: handle fused CMP_LONG/IF_xxZ case
2536 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2537 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002538 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2539 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002540 } else {
2541 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2542 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2543 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2544 }
2545 opCondBranch(cUnit, cond, taken);
buzbee2cfc6392012-05-07 14:51:40 -07002546 // Fallthrough
2547 opUnconditionalBranch(cUnit, fallThrough);
2548}
2549
2550void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2551 llvm::Function* callee)
2552{
2553 UNIMPLEMENTED(FATAL);
2554}
2555
buzbee2cfc6392012-05-07 14:51:40 -07002556void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2557{
buzbee4f1181f2012-06-22 13:52:12 -07002558 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002559 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2560 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002561 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2562 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002563 if (rlSrc.wide) {
2564 storeValueWide(cUnit, rlDest, rlSrc);
2565 } else {
2566 storeValue(cUnit, rlDest, rlSrc);
2567 }
2568}
2569
2570// Note: Immediate arg is a ConstantInt regardless of result type
2571void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2572{
buzbee4f1181f2012-06-22 13:52:12 -07002573 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002574 llvm::ConstantInt* src =
2575 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2576 uint64_t immval = src->getZExtValue();
2577 RegLocation rlDest = getLoc(cUnit, callInst);
2578 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2579 if (rlDest.wide) {
2580 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2581 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2582 storeValueWide(cUnit, rlDest, rlResult);
2583 } else {
2584 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2585 storeValue(cUnit, rlDest, rlResult);
2586 }
2587}
2588
buzbee101305f2012-06-28 18:00:56 -07002589void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2590 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002591{
buzbee4f1181f2012-06-22 13:52:12 -07002592 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002593 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002594 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002595 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002596 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002597 if (isString) {
2598 genConstString(cUnit, index, rlDest);
2599 } else {
2600 genConstClass(cUnit, index, rlDest);
2601 }
2602}
2603
2604void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2605{
2606 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2607 llvm::ConstantInt* offsetVal =
2608 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2609 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2610 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002611}
2612
buzbee4f1181f2012-06-22 13:52:12 -07002613void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2614{
buzbee32412962012-06-26 16:27:56 -07002615 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002616 llvm::ConstantInt* typeIdxVal =
2617 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2618 uint32_t typeIdx = typeIdxVal->getZExtValue();
2619 RegLocation rlDest = getLoc(cUnit, callInst);
2620 genNewInstance(cUnit, typeIdx, rlDest);
2621}
2622
buzbee8fa0fda2012-06-27 15:44:52 -07002623void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2624{
2625 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2626 llvm::ConstantInt* typeIdxVal =
2627 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2628 uint32_t typeIdx = typeIdxVal->getZExtValue();
2629 llvm::Value* len = callInst->getArgOperand(1);
2630 RegLocation rlLen = getLoc(cUnit, len);
2631 RegLocation rlDest = getLoc(cUnit, callInst);
2632 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2633}
2634
2635void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2636{
2637 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2638 llvm::ConstantInt* typeIdxVal =
2639 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2640 uint32_t typeIdx = typeIdxVal->getZExtValue();
2641 llvm::Value* src = callInst->getArgOperand(1);
2642 RegLocation rlSrc = getLoc(cUnit, src);
2643 RegLocation rlDest = getLoc(cUnit, callInst);
2644 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2645}
2646
buzbee32412962012-06-26 16:27:56 -07002647void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2648{
2649 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2650 llvm::Value* src = callInst->getArgOperand(0);
2651 RegLocation rlSrc = getLoc(cUnit, src);
2652 genThrow(cUnit, rlSrc);
2653}
2654
buzbee8fa0fda2012-06-27 15:44:52 -07002655void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2656 llvm::CallInst* callInst)
2657{
2658 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2659 llvm::ConstantInt* optFlags =
2660 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2661 llvm::Value* src = callInst->getArgOperand(1);
2662 RegLocation rlSrc = getLoc(cUnit, src);
2663 if (isEnter) {
2664 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2665 } else {
2666 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2667 }
2668}
2669
buzbee76592632012-06-29 15:18:35 -07002670void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002671{
2672 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2673 llvm::ConstantInt* optFlags =
2674 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2675 llvm::Value* src = callInst->getArgOperand(1);
2676 RegLocation rlSrc = getLoc(cUnit, src);
2677 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2678 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2679 RegLocation rlDest = getLoc(cUnit, callInst);
2680 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2681 int lenOffset = Array::LengthOffset().Int32Value();
2682 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2683 storeValue(cUnit, rlDest, rlResult);
2684}
2685
buzbee32412962012-06-26 16:27:56 -07002686void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2687{
buzbee32412962012-06-26 16:27:56 -07002688 RegLocation rlDest = getLoc(cUnit, callInst);
Ian Rogers474b6da2012-09-25 00:20:38 -07002689 genMoveException(cUnit, rlDest);
buzbee32412962012-06-26 16:27:56 -07002690}
2691
buzbee4f1181f2012-06-22 13:52:12 -07002692void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2693 bool isObject)
2694{
buzbee32412962012-06-26 16:27:56 -07002695 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002696 llvm::ConstantInt* typeIdxVal =
2697 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2698 uint32_t typeIdx = typeIdxVal->getZExtValue();
2699 RegLocation rlDest = getLoc(cUnit, callInst);
2700 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2701}
2702
buzbee8fa0fda2012-06-27 15:44:52 -07002703void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2704 bool isObject)
2705{
2706 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2707 llvm::ConstantInt* typeIdxVal =
2708 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2709 uint32_t typeIdx = typeIdxVal->getZExtValue();
2710 llvm::Value* src = callInst->getArgOperand(1);
2711 RegLocation rlSrc = getLoc(cUnit, src);
2712 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2713}
2714
2715void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2716 int scale)
2717{
2718 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2719 llvm::ConstantInt* optFlags =
2720 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2721 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2722 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2723 RegLocation rlDest = getLoc(cUnit, callInst);
2724 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2725 rlDest, scale);
2726}
2727
2728void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002729 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002730{
2731 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2732 llvm::ConstantInt* optFlags =
2733 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2734 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2735 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2736 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002737 if (isObject) {
2738 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2739 rlSrc, scale);
2740 } else {
2741 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2742 rlSrc, scale);
2743 }
2744}
2745
2746void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2747{
2748 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2749}
2750
2751void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2752 OpSize size, int scale)
2753{
2754 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002755}
2756
buzbee101305f2012-06-28 18:00:56 -07002757void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2758 bool isWide, bool isObj)
2759{
2760 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2761 llvm::ConstantInt* optFlags =
2762 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2763 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2764 llvm::ConstantInt* fieldIdx =
2765 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2766 RegLocation rlDest = getLoc(cUnit, callInst);
2767 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2768 size, rlDest, rlObj, isWide, isObj);
2769}
2770
2771void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2772 bool isWide, bool isObj)
2773{
2774 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2775 llvm::ConstantInt* optFlags =
2776 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2777 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2778 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2779 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002780 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002781 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2782 size, rlSrc, rlObj, isWide, isObj);
2783}
2784
2785void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2786{
2787 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2788 llvm::ConstantInt* typeIdx =
2789 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2790 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2791 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2792}
2793
buzbee76592632012-06-29 15:18:35 -07002794void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2795 Instruction::Code opcode)
2796{
2797 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2798 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2799 RegLocation rlDest = getLoc(cUnit, callInst);
2800 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2801}
2802
2803void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2804{
2805 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2806 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2807 RegLocation rlDest = getLoc(cUnit, callInst);
2808 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2809}
2810
buzbeef58c12c2012-07-03 15:06:29 -07002811void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2812{
2813 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2814 DCHECK(swInst != NULL);
2815 llvm::Value* testVal = swInst->getCondition();
2816 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2817 DCHECK(tableOffsetNode != NULL);
2818 llvm::ConstantInt* tableOffsetValue =
2819 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2820 int32_t tableOffset = tableOffsetValue->getSExtValue();
2821 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeeeaf09bc2012-11-15 14:51:41 -08002822 const uint16_t* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2823 uint16_t tableMagic = *table;
buzbeea1da8a52012-07-09 14:00:21 -07002824 if (tableMagic == 0x100) {
2825 genPackedSwitch(cUnit, tableOffset, rlSrc);
2826 } else {
2827 DCHECK_EQ(tableMagic, 0x200);
2828 genSparseSwitch(cUnit, tableOffset, rlSrc);
2829 }
buzbeef58c12c2012-07-03 15:06:29 -07002830}
2831
buzbee6969d502012-06-15 16:40:31 -07002832void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002833 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002834{
buzbeecbd6d442012-11-17 14:11:25 -08002835 CallInfo* info = static_cast<CallInfo*>(oatNew(cUnit, sizeof(CallInfo), true, kAllocMisc));
buzbee8fa0fda2012-06-27 15:44:52 -07002836 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002837 info->result.location = kLocInvalid;
2838 } else {
2839 info->result = getLoc(cUnit, callInst);
2840 }
2841 llvm::ConstantInt* invokeTypeVal =
2842 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2843 llvm::ConstantInt* methodIndexVal =
2844 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2845 llvm::ConstantInt* optFlagsVal =
2846 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2847 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2848 info->index = methodIndexVal->getZExtValue();
2849 info->optFlags = optFlagsVal->getZExtValue();
2850 info->offset = cUnit->currentDalvikOffset;
2851
buzbee6969d502012-06-15 16:40:31 -07002852 // Count the argument words, and then build argument array.
2853 info->numArgWords = 0;
2854 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2855 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2856 info->numArgWords += tLoc.wide ? 2 : 1;
2857 }
buzbeecbd6d442012-11-17 14:11:25 -08002858 info->args = (info->numArgWords == 0) ? NULL : static_cast<RegLocation*>
2859 (oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc));
buzbee6969d502012-06-15 16:40:31 -07002860 // Now, fill in the location records, synthesizing high loc of wide vals
2861 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002862 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002863 if (info->args[next].wide) {
2864 next++;
2865 // TODO: Might make sense to mark this as an invalid loc
2866 info->args[next].origSReg = info->args[next-1].origSReg+1;
2867 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2868 }
2869 next++;
2870 }
buzbee4f4dfc72012-07-02 14:54:44 -07002871 // TODO - rework such that we no longer need isRange
2872 info->isRange = (info->numArgWords > 5);
2873
buzbee76592632012-06-29 15:18:35 -07002874 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002875 genFilledNewArray(cUnit, info);
2876 } else {
2877 genInvoke(cUnit, info);
2878 }
buzbee6969d502012-06-15 16:40:31 -07002879}
2880
buzbeead8f15e2012-06-18 14:49:45 -07002881/* Look up the RegLocation associated with a Value. Must already be defined */
2882RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2883{
2884 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2885 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2886 return it->second;
2887}
2888
buzbee2cfc6392012-05-07 14:51:40 -07002889bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2890{
buzbee0967a252012-09-14 10:43:54 -07002891 while (cUnit->llvmBlocks.find(bb) == cUnit->llvmBlocks.end()) {
2892 llvm::BasicBlock* nextBB = NULL;
2893 cUnit->llvmBlocks.insert(bb);
2894 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2895 // Define the starting label
2896 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2897 // Extract the type and starting offset from the block's name
buzbee951c0a12012-10-03 16:31:39 -07002898 char blockType = kInvalidBlock;
2899 if (isEntry) {
2900 blockType = kNormalBlock;
2901 blockLabel->operands[0] = 0;
2902 } else if (!bb->hasName()) {
2903 blockType = kNormalBlock;
2904 blockLabel->operands[0] = DexFile::kDexNoIndex;
buzbee0967a252012-09-14 10:43:54 -07002905 } else {
buzbee951c0a12012-10-03 16:31:39 -07002906 std::string blockName = bb->getName().str();
2907 int dummy;
2908 sscanf(blockName.c_str(), kLabelFormat, &blockType, &blockLabel->operands[0], &dummy);
2909 cUnit->currentDalvikOffset = blockLabel->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002910 }
buzbee951c0a12012-10-03 16:31:39 -07002911 DCHECK((blockType == kNormalBlock) || (blockType == kCatchBlock));
2912 cUnit->currentDalvikOffset = blockLabel->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002913 // Set the label kind
2914 blockLabel->opcode = kPseudoNormalBlockLabel;
2915 // Insert the label
2916 oatAppendLIR(cUnit, blockLabel);
buzbee2cfc6392012-05-07 14:51:40 -07002917
buzbee0967a252012-09-14 10:43:54 -07002918 LIR* headLIR = NULL;
buzbee8320f382012-09-11 16:29:42 -07002919
buzbee0967a252012-09-14 10:43:54 -07002920 if (blockType == kCatchBlock) {
Bill Buzbeea5b30242012-09-28 07:19:44 -07002921 headLIR = newLIR0(cUnit, kPseudoExportedPC);
buzbee0967a252012-09-14 10:43:54 -07002922 }
buzbee8320f382012-09-11 16:29:42 -07002923
buzbee0967a252012-09-14 10:43:54 -07002924 // Free temp registers and reset redundant store tracking */
2925 oatResetRegPool(cUnit);
2926 oatResetDefTracking(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002927
buzbee0967a252012-09-14 10:43:54 -07002928 //TODO: restore oat incoming liveness optimization
2929 oatClobberAllRegs(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002930
buzbee0967a252012-09-14 10:43:54 -07002931 if (isEntry) {
buzbeecbd6d442012-11-17 14:11:25 -08002932 RegLocation* argLocs = static_cast<RegLocation*>
2933 (oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc));
buzbee0967a252012-09-14 10:43:54 -07002934 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2935 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2936 // Skip past Method*
2937 it++;
2938 for (unsigned i = 0; it != it_end; ++it) {
2939 llvm::Value* val = it;
2940 argLocs[i++] = valToLoc(cUnit, val);
2941 llvm::Type* ty = val->getType();
2942 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2943 argLocs[i] = argLocs[i-1];
2944 argLocs[i].lowReg = argLocs[i].highReg;
2945 argLocs[i].origSReg++;
2946 argLocs[i].sRegLow = INVALID_SREG;
2947 argLocs[i].highWord = true;
2948 i++;
2949 }
2950 }
2951 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
2952 }
2953
2954 // Visit all of the instructions in the block
2955 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2956 llvm::Instruction* inst = it;
2957 llvm::BasicBlock::iterator nextIt = ++it;
2958 // Extract the Dalvik offset from the instruction
2959 uint32_t opcode = inst->getOpcode();
2960 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2961 if (dexOffsetNode != NULL) {
2962 llvm::ConstantInt* dexOffsetValue =
2963 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2964 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2965 }
2966
2967 oatResetRegPool(cUnit);
2968 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2969 oatClobberAllRegs(cUnit);
2970 }
2971
2972 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2973 oatResetDefTracking(cUnit);
2974 }
2975
2976 #ifndef NDEBUG
2977 /* Reset temp tracking sanity check */
2978 cUnit->liveSReg = INVALID_SREG;
2979 #endif
2980
2981 // TODO: use llvm opcode name here instead of "boundary" if verbose
2982 LIR* boundaryLIR = markBoundary(cUnit, cUnit->currentDalvikOffset, "boundary");
2983
2984 /* Remember the first LIR for thisl block*/
2985 if (headLIR == NULL) {
2986 headLIR = boundaryLIR;
2987 headLIR->defMask = ENCODE_ALL;
2988 }
2989
2990 switch(opcode) {
2991
2992 case llvm::Instruction::ICmp: {
2993 llvm::Instruction* nextInst = nextIt;
2994 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2995 if (brInst != NULL /* and... */) {
2996 cvtICmpBr(cUnit, inst, brInst);
2997 ++it;
2998 } else {
2999 cvtICmp(cUnit, inst);
3000 }
3001 }
3002 break;
3003
3004 case llvm::Instruction::Call: {
3005 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
3006 llvm::Function* callee = callInst->getCalledFunction();
3007 greenland::IntrinsicHelper::IntrinsicId id =
3008 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3009 switch (id) {
3010 case greenland::IntrinsicHelper::AllocaShadowFrame:
3011 case greenland::IntrinsicHelper::SetShadowFrameEntry:
3012 case greenland::IntrinsicHelper::PopShadowFrame:
TDYa1278e950c12012-11-02 09:58:19 -07003013 case greenland::IntrinsicHelper::SetVReg:
buzbee0967a252012-09-14 10:43:54 -07003014 // Ignore shadow frame stuff for quick compiler
3015 break;
3016 case greenland::IntrinsicHelper::CopyInt:
3017 case greenland::IntrinsicHelper::CopyObj:
3018 case greenland::IntrinsicHelper::CopyFloat:
3019 case greenland::IntrinsicHelper::CopyLong:
3020 case greenland::IntrinsicHelper::CopyDouble:
3021 cvtCopy(cUnit, callInst);
3022 break;
3023 case greenland::IntrinsicHelper::ConstInt:
3024 case greenland::IntrinsicHelper::ConstObj:
3025 case greenland::IntrinsicHelper::ConstLong:
3026 case greenland::IntrinsicHelper::ConstFloat:
3027 case greenland::IntrinsicHelper::ConstDouble:
3028 cvtConst(cUnit, callInst);
3029 break;
3030 case greenland::IntrinsicHelper::DivInt:
3031 case greenland::IntrinsicHelper::DivLong:
3032 cvtBinOp(cUnit, kOpDiv, inst);
3033 break;
3034 case greenland::IntrinsicHelper::RemInt:
3035 case greenland::IntrinsicHelper::RemLong:
3036 cvtBinOp(cUnit, kOpRem, inst);
3037 break;
3038 case greenland::IntrinsicHelper::MethodInfo:
3039 // Already dealt with - just ignore it here.
3040 break;
3041 case greenland::IntrinsicHelper::CheckSuspend:
3042 genSuspendTest(cUnit, 0 /* optFlags already applied */);
3043 break;
3044 case greenland::IntrinsicHelper::HLInvokeObj:
3045 case greenland::IntrinsicHelper::HLInvokeFloat:
3046 case greenland::IntrinsicHelper::HLInvokeDouble:
3047 case greenland::IntrinsicHelper::HLInvokeLong:
3048 case greenland::IntrinsicHelper::HLInvokeInt:
3049 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
3050 break;
3051 case greenland::IntrinsicHelper::HLInvokeVoid:
3052 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
3053 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003054 case greenland::IntrinsicHelper::HLFilledNewArray:
buzbee0967a252012-09-14 10:43:54 -07003055 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
3056 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003057 case greenland::IntrinsicHelper::HLFillArrayData:
buzbee0967a252012-09-14 10:43:54 -07003058 cvtFillArrayData(cUnit, callInst);
3059 break;
3060 case greenland::IntrinsicHelper::ConstString:
3061 cvtConstObject(cUnit, callInst, true /* isString */);
3062 break;
3063 case greenland::IntrinsicHelper::ConstClass:
3064 cvtConstObject(cUnit, callInst, false /* isString */);
3065 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003066 case greenland::IntrinsicHelper::HLCheckCast:
buzbee0967a252012-09-14 10:43:54 -07003067 cvtCheckCast(cUnit, callInst);
3068 break;
3069 case greenland::IntrinsicHelper::NewInstance:
3070 cvtNewInstance(cUnit, callInst);
3071 break;
3072 case greenland::IntrinsicHelper::HLSgetObject:
3073 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
3074 break;
3075 case greenland::IntrinsicHelper::HLSget:
3076 case greenland::IntrinsicHelper::HLSgetFloat:
3077 case greenland::IntrinsicHelper::HLSgetBoolean:
3078 case greenland::IntrinsicHelper::HLSgetByte:
3079 case greenland::IntrinsicHelper::HLSgetChar:
3080 case greenland::IntrinsicHelper::HLSgetShort:
3081 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
3082 break;
3083 case greenland::IntrinsicHelper::HLSgetWide:
3084 case greenland::IntrinsicHelper::HLSgetDouble:
3085 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
3086 break;
3087 case greenland::IntrinsicHelper::HLSput:
3088 case greenland::IntrinsicHelper::HLSputFloat:
3089 case greenland::IntrinsicHelper::HLSputBoolean:
3090 case greenland::IntrinsicHelper::HLSputByte:
3091 case greenland::IntrinsicHelper::HLSputChar:
3092 case greenland::IntrinsicHelper::HLSputShort:
3093 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
3094 break;
3095 case greenland::IntrinsicHelper::HLSputWide:
3096 case greenland::IntrinsicHelper::HLSputDouble:
3097 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
3098 break;
3099 case greenland::IntrinsicHelper::HLSputObject:
3100 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
3101 break;
3102 case greenland::IntrinsicHelper::GetException:
3103 cvtMoveException(cUnit, callInst);
3104 break;
TDYa127f71bf5a2012-07-29 20:09:52 -07003105 case greenland::IntrinsicHelper::HLThrowException:
buzbee0967a252012-09-14 10:43:54 -07003106 cvtThrow(cUnit, callInst);
3107 break;
3108 case greenland::IntrinsicHelper::MonitorEnter:
3109 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
3110 break;
3111 case greenland::IntrinsicHelper::MonitorExit:
3112 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
3113 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003114 case greenland::IntrinsicHelper::OptArrayLength:
buzbee0967a252012-09-14 10:43:54 -07003115 cvtArrayLength(cUnit, callInst);
3116 break;
3117 case greenland::IntrinsicHelper::NewArray:
3118 cvtNewArray(cUnit, callInst);
3119 break;
3120 case greenland::IntrinsicHelper::InstanceOf:
3121 cvtInstanceOf(cUnit, callInst);
3122 break;
3123
3124 case greenland::IntrinsicHelper::HLArrayGet:
3125 case greenland::IntrinsicHelper::HLArrayGetObject:
3126 case greenland::IntrinsicHelper::HLArrayGetFloat:
3127 cvtAget(cUnit, callInst, kWord, 2);
3128 break;
3129 case greenland::IntrinsicHelper::HLArrayGetWide:
3130 case greenland::IntrinsicHelper::HLArrayGetDouble:
3131 cvtAget(cUnit, callInst, kLong, 3);
3132 break;
3133 case greenland::IntrinsicHelper::HLArrayGetBoolean:
3134 cvtAget(cUnit, callInst, kUnsignedByte, 0);
3135 break;
3136 case greenland::IntrinsicHelper::HLArrayGetByte:
3137 cvtAget(cUnit, callInst, kSignedByte, 0);
3138 break;
3139 case greenland::IntrinsicHelper::HLArrayGetChar:
3140 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
3141 break;
3142 case greenland::IntrinsicHelper::HLArrayGetShort:
3143 cvtAget(cUnit, callInst, kSignedHalf, 1);
3144 break;
3145
3146 case greenland::IntrinsicHelper::HLArrayPut:
3147 case greenland::IntrinsicHelper::HLArrayPutFloat:
3148 cvtAputPrimitive(cUnit, callInst, kWord, 2);
3149 break;
3150 case greenland::IntrinsicHelper::HLArrayPutObject:
3151 cvtAputObj(cUnit, callInst);
3152 break;
3153 case greenland::IntrinsicHelper::HLArrayPutWide:
3154 case greenland::IntrinsicHelper::HLArrayPutDouble:
3155 cvtAputPrimitive(cUnit, callInst, kLong, 3);
3156 break;
3157 case greenland::IntrinsicHelper::HLArrayPutBoolean:
3158 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
3159 break;
3160 case greenland::IntrinsicHelper::HLArrayPutByte:
3161 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
3162 break;
3163 case greenland::IntrinsicHelper::HLArrayPutChar:
3164 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
3165 break;
3166 case greenland::IntrinsicHelper::HLArrayPutShort:
3167 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
3168 break;
3169
3170 case greenland::IntrinsicHelper::HLIGet:
3171 case greenland::IntrinsicHelper::HLIGetFloat:
3172 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3173 break;
3174 case greenland::IntrinsicHelper::HLIGetObject:
3175 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3176 break;
3177 case greenland::IntrinsicHelper::HLIGetWide:
3178 case greenland::IntrinsicHelper::HLIGetDouble:
3179 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3180 break;
3181 case greenland::IntrinsicHelper::HLIGetBoolean:
3182 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3183 false /* obj */);
3184 break;
3185 case greenland::IntrinsicHelper::HLIGetByte:
3186 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3187 false /* obj */);
3188 break;
3189 case greenland::IntrinsicHelper::HLIGetChar:
3190 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3191 false /* obj */);
3192 break;
3193 case greenland::IntrinsicHelper::HLIGetShort:
3194 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3195 false /* obj */);
3196 break;
3197
3198 case greenland::IntrinsicHelper::HLIPut:
3199 case greenland::IntrinsicHelper::HLIPutFloat:
3200 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3201 break;
3202 case greenland::IntrinsicHelper::HLIPutObject:
3203 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3204 break;
3205 case greenland::IntrinsicHelper::HLIPutWide:
3206 case greenland::IntrinsicHelper::HLIPutDouble:
3207 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3208 break;
3209 case greenland::IntrinsicHelper::HLIPutBoolean:
3210 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3211 false /* obj */);
3212 break;
3213 case greenland::IntrinsicHelper::HLIPutByte:
3214 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3215 false /* obj */);
3216 break;
3217 case greenland::IntrinsicHelper::HLIPutChar:
3218 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3219 false /* obj */);
3220 break;
3221 case greenland::IntrinsicHelper::HLIPutShort:
3222 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3223 false /* obj */);
3224 break;
3225
3226 case greenland::IntrinsicHelper::IntToChar:
3227 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3228 break;
3229 case greenland::IntrinsicHelper::IntToShort:
3230 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3231 break;
3232 case greenland::IntrinsicHelper::IntToByte:
3233 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3234 break;
3235
TDYa1274ec8ccd2012-08-11 07:04:57 -07003236 case greenland::IntrinsicHelper::F2I:
3237 case greenland::IntrinsicHelper::D2I:
3238 case greenland::IntrinsicHelper::F2L:
3239 case greenland::IntrinsicHelper::D2L:
3240 cvtFPToInt(cUnit, callInst);
3241 break;
3242
buzbee0967a252012-09-14 10:43:54 -07003243 case greenland::IntrinsicHelper::CmplFloat:
3244 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3245 break;
3246 case greenland::IntrinsicHelper::CmpgFloat:
3247 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3248 break;
3249 case greenland::IntrinsicHelper::CmplDouble:
3250 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3251 break;
3252 case greenland::IntrinsicHelper::CmpgDouble:
3253 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3254 break;
3255
3256 case greenland::IntrinsicHelper::CmpLong:
3257 cvtLongCompare(cUnit, callInst);
3258 break;
3259
3260 case greenland::IntrinsicHelper::SHLLong:
3261 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
3262 break;
3263 case greenland::IntrinsicHelper::SHRLong:
3264 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3265 break;
3266 case greenland::IntrinsicHelper::USHRLong:
3267 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3268 break;
3269 case greenland::IntrinsicHelper::SHLInt:
3270 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3271 break;
3272 case greenland::IntrinsicHelper::SHRInt:
3273 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3274 break;
3275 case greenland::IntrinsicHelper::USHRInt:
3276 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3277 break;
3278
3279 case greenland::IntrinsicHelper::CatchTargets: {
3280 llvm::SwitchInst* swInst =
3281 llvm::dyn_cast<llvm::SwitchInst>(nextIt);
3282 DCHECK(swInst != NULL);
3283 /*
3284 * Discard the edges and the following conditional branch.
3285 * Do a direct branch to the default target (which is the
3286 * "work" portion of the pair.
3287 * TODO: awful code layout - rework
3288 */
3289 llvm::BasicBlock* targetBB = swInst->getDefaultDest();
3290 DCHECK(targetBB != NULL);
3291 opUnconditionalBranch(cUnit,
3292 cUnit->blockToLabelMap.Get(targetBB));
3293 ++it;
3294 // Set next bb to default target - improves code layout
3295 nextBB = targetBB;
3296 }
3297 break;
3298
3299 default:
buzbeecbd6d442012-11-17 14:11:25 -08003300 LOG(FATAL) << "Unexpected intrinsic " << cUnit->intrinsic_helper->GetName(id);
buzbee0967a252012-09-14 10:43:54 -07003301 }
3302 }
3303 break;
3304
3305 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3306 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3307 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3308 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3309 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3310 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3311 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3312 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3313 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
3314 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3315 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
3316 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3317 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3318 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3319 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3320 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
3321 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003322 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3323 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3324 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
3325
3326 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3327 break;
3328 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3329 break;
3330
3331 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3332
3333 case llvm::Instruction::Unreachable:
3334 break; // FIXME: can we really ignore these?
3335
3336 case llvm::Instruction::Shl:
3337 case llvm::Instruction::LShr:
3338 case llvm::Instruction::AShr:
3339 case llvm::Instruction::Invoke:
3340 case llvm::Instruction::FPToUI:
TDYa1274ec8ccd2012-08-11 07:04:57 -07003341 case llvm::Instruction::FPToSI:
buzbee0967a252012-09-14 10:43:54 -07003342 case llvm::Instruction::UIToFP:
3343 case llvm::Instruction::PtrToInt:
3344 case llvm::Instruction::IntToPtr:
3345 case llvm::Instruction::FCmp:
3346 case llvm::Instruction::URem:
3347 case llvm::Instruction::UDiv:
3348 case llvm::Instruction::Resume:
3349 case llvm::Instruction::Alloca:
3350 case llvm::Instruction::GetElementPtr:
3351 case llvm::Instruction::Fence:
3352 case llvm::Instruction::AtomicCmpXchg:
3353 case llvm::Instruction::AtomicRMW:
3354 case llvm::Instruction::BitCast:
3355 case llvm::Instruction::VAArg:
3356 case llvm::Instruction::Select:
3357 case llvm::Instruction::UserOp1:
3358 case llvm::Instruction::UserOp2:
3359 case llvm::Instruction::ExtractElement:
3360 case llvm::Instruction::InsertElement:
3361 case llvm::Instruction::ShuffleVector:
3362 case llvm::Instruction::ExtractValue:
3363 case llvm::Instruction::InsertValue:
3364 case llvm::Instruction::LandingPad:
3365 case llvm::Instruction::IndirectBr:
3366 case llvm::Instruction::Load:
3367 case llvm::Instruction::Store:
3368 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3369
3370 default:
3371 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3372 break;
buzbeead8f15e2012-06-18 14:49:45 -07003373 }
3374 }
buzbee2cfc6392012-05-07 14:51:40 -07003375
buzbee0967a252012-09-14 10:43:54 -07003376 if (headLIR != NULL) {
3377 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
buzbee2cfc6392012-05-07 14:51:40 -07003378 }
buzbee0967a252012-09-14 10:43:54 -07003379 if (nextBB != NULL) {
3380 bb = nextBB;
3381 nextBB = NULL;
buzbee6969d502012-06-15 16:40:31 -07003382 }
buzbee6969d502012-06-15 16:40:31 -07003383 }
buzbee2cfc6392012-05-07 14:51:40 -07003384 return false;
3385}
3386
3387/*
3388 * Convert LLVM_IR to MIR:
3389 * o Iterate through the LLVM_IR and construct a graph using
3390 * standard MIR building blocks.
3391 * o Perform a basic-block optimization pass to remove unnecessary
3392 * store/load sequences.
3393 * o Convert the LLVM Value operands into RegLocations where applicable.
3394 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3395 * o Perform register promotion
3396 * o Iterate through the graph a basic block at a time, generating
3397 * LIR.
3398 * o Assemble LIR as usual.
3399 * o Profit.
3400 */
3401void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3402{
buzbeead8f15e2012-06-18 14:49:45 -07003403 llvm::Function* func = cUnit->func;
3404 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003405 // Allocate a list for LIR basic block labels
3406 cUnit->blockLabelList =
buzbeecbd6d442012-11-17 14:11:25 -08003407 static_cast<LIR*>(oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR));
buzbeea1da8a52012-07-09 14:00:21 -07003408 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003409 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003410 for (llvm::Function::iterator i = func->begin(),
3411 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003412 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3413 &labelList[nextLabel++]);
3414 }
buzbeead8f15e2012-06-18 14:49:45 -07003415
3416 /*
3417 * Keep honest - clear regLocations, Value => RegLocation,
3418 * promotion map and VmapTables.
3419 */
3420 cUnit->locMap.clear(); // Start fresh
3421 cUnit->regLocation = NULL;
3422 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3423 i++) {
3424 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3425 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3426 }
3427 cUnit->coreSpillMask = 0;
3428 cUnit->numCoreSpills = 0;
3429 cUnit->fpSpillMask = 0;
3430 cUnit->numFPSpills = 0;
3431 cUnit->coreVmapTable.clear();
3432 cUnit->fpVmapTable.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003433
3434 /*
3435 * At this point, we've lost all knowledge of register promotion.
3436 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003437 * exists - not required for correctness). Normally, this will
3438 * be the first instruction we encounter, so we won't have to iterate
3439 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003440 */
buzbeeca7a5e42012-08-20 11:12:18 -07003441 for (llvm::inst_iterator i = llvm::inst_begin(func),
3442 e = llvm::inst_end(func); i != e; ++i) {
3443 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(&*i);
3444 if (callInst != NULL) {
3445 llvm::Function* callee = callInst->getCalledFunction();
3446 greenland::IntrinsicHelper::IntrinsicId id =
3447 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3448 if (id == greenland::IntrinsicHelper::MethodInfo) {
3449 if (cUnit->printMe) {
3450 LOG(INFO) << "Found MethodInfo";
3451 }
3452 llvm::MDNode* regInfoNode = callInst->getMetadata("RegInfo");
3453 if (regInfoNode != NULL) {
3454 llvm::ConstantInt* numInsValue =
3455 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(0));
3456 llvm::ConstantInt* numRegsValue =
3457 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(1));
3458 llvm::ConstantInt* numOutsValue =
3459 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(2));
3460 llvm::ConstantInt* numCompilerTempsValue =
3461 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(3));
3462 llvm::ConstantInt* numSSARegsValue =
3463 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(4));
3464 if (cUnit->printMe) {
3465 LOG(INFO) << "RegInfo - Ins:" << numInsValue->getZExtValue()
3466 << ", Regs:" << numRegsValue->getZExtValue()
3467 << ", Outs:" << numOutsValue->getZExtValue()
3468 << ", CTemps:" << numCompilerTempsValue->getZExtValue()
3469 << ", SSARegs:" << numSSARegsValue->getZExtValue();
3470 }
3471 }
3472 llvm::MDNode* pmapInfoNode = callInst->getMetadata("PromotionMap");
3473 if (pmapInfoNode != NULL) {
3474 int elems = pmapInfoNode->getNumOperands();
3475 if (cUnit->printMe) {
3476 LOG(INFO) << "PMap size: " << elems;
3477 }
3478 for (int i = 0; i < elems; i++) {
3479 llvm::ConstantInt* rawMapData =
3480 static_cast<llvm::ConstantInt*>(pmapInfoNode->getOperand(i));
3481 uint32_t mapData = rawMapData->getZExtValue();
3482 PromotionMap* p = &cUnit->promotionMap[i];
3483 p->firstInPair = (mapData >> 24) & 0xff;
3484 p->fpReg = (mapData >> 16) & 0xff;
3485 p->coreReg = (mapData >> 8) & 0xff;
3486 p->fpLocation = static_cast<RegLocationType>((mapData >> 4) & 0xf);
3487 if (p->fpLocation == kLocPhysReg) {
3488 oatRecordFpPromotion(cUnit, p->fpReg, i);
3489 }
3490 p->coreLocation = static_cast<RegLocationType>(mapData & 0xf);
3491 if (p->coreLocation == kLocPhysReg) {
3492 oatRecordCorePromotion(cUnit, p->coreReg, i);
3493 }
3494 }
3495 if (cUnit->printMe) {
3496 oatDumpPromotionMap(cUnit);
3497 }
3498 }
3499 break;
3500 }
3501 }
3502 }
3503 oatAdjustSpillMask(cUnit);
3504 cUnit->frameSize = oatComputeFrameSize(cUnit);
buzbeead8f15e2012-06-18 14:49:45 -07003505
3506 // Create RegLocations for arguments
3507 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3508 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3509 for (; it != it_end; ++it) {
3510 llvm::Value* val = it;
3511 createLocFromValue(cUnit, val);
3512 }
3513 // Create RegLocations for all non-argument defintions
3514 for (llvm::inst_iterator i = llvm::inst_begin(func),
3515 e = llvm::inst_end(func); i != e; ++i) {
3516 llvm::Value* val = &*i;
3517 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3518 createLocFromValue(cUnit, val);
3519 }
3520 }
3521
buzbee2cfc6392012-05-07 14:51:40 -07003522 // Walk the blocks, generating code.
3523 for (llvm::Function::iterator i = cUnit->func->begin(),
3524 e = cUnit->func->end(); i != e; ++i) {
3525 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3526 }
3527
3528 handleSuspendLaunchpads(cUnit);
3529
3530 handleThrowLaunchpads(cUnit);
3531
3532 handleIntrinsicLaunchpads(cUnit);
3533
buzbee692be802012-08-29 15:52:59 -07003534 cUnit->func->eraseFromParent();
3535 cUnit->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003536}
3537
3538
3539} // namespace art