blob: d6f1ae9034f1de09ea5da1d20164a312725fbc90 [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{
49 return (llvm::Value*)oatGrowableListGetElement(&cUnit->llvmValues, sReg);
50}
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);
63 cUnit->llvmValues.elemList[sReg] = (intptr_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) {
buzbee0967a252012-09-14 10:43:54 -0700176 LOG(INFO) << "Promoted wide " << s << " to regs " << static_cast<int>(loc.lowReg)
buzbeeca7a5e42012-08-20 11:12:18 -0700177 << "/" << loc.highReg;
178 } else {
buzbee0967a252012-09-14 10:43:54 -0700179 LOG(INFO) << "Promoted " << s << " to reg " << static_cast<int>(loc.lowReg);
buzbeeca7a5e42012-08-20 11:12:18 -0700180 }
181 }
buzbeead8f15e2012-06-18 14:49:45 -0700182 cUnit->locMap.Put(val, loc);
183}
buzbee2cfc6392012-05-07 14:51:40 -0700184void initIR(CompilationUnit* cUnit)
185{
buzbee4df2bbd2012-10-11 14:46:06 -0700186 LLVMInfo* llvmInfo = cUnit->llvm_info;
187 if (llvmInfo == NULL) {
188 CompilerTls* tls = cUnit->compiler->GetTls();
189 CHECK(tls != NULL);
190 llvmInfo = static_cast<LLVMInfo*>(tls->GetLLVMInfo());
191 if (llvmInfo == NULL) {
192 llvmInfo = new LLVMInfo();
193 tls->SetLLVMInfo(llvmInfo);
194 }
195 }
196 cUnit->context = llvmInfo->GetLLVMContext();
197 cUnit->module = llvmInfo->GetLLVMModule();
198 cUnit->intrinsic_helper = llvmInfo->GetIntrinsicHelper();
199 cUnit->irb = llvmInfo->GetIRBuilder();
buzbee2cfc6392012-05-07 14:51:40 -0700200}
201
202const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
203 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
204}
205
buzbeef58c12c2012-07-03 15:06:29 -0700206llvm::BasicBlock* findCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
207{
208 BasicBlock* bb = oatFindBlock(cUnit, vaddr);
209 DCHECK(bb != NULL);
210 return getLLVMBlock(cUnit, bb->id);
211}
212
213void convertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
214 int32_t tableOffset, RegLocation rlSrc)
215{
216 const Instruction::PackedSwitchPayload* payload =
217 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
218 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
219
220 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
221
222 llvm::SwitchInst* sw =
223 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
224 payload->case_count);
225
226 for (uint16_t i = 0; i < payload->case_count; ++i) {
227 llvm::BasicBlock* llvmBB =
228 findCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
229 sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
230 }
231 llvm::MDNode* switchNode =
232 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
233 sw->setMetadata("SwitchTable", switchNode);
234 bb->taken = NULL;
235 bb->fallThrough = NULL;
236}
237
buzbeea1da8a52012-07-09 14:00:21 -0700238void convertSparseSwitch(CompilationUnit* cUnit, BasicBlock* bb,
239 int32_t tableOffset, RegLocation rlSrc)
240{
241 const Instruction::SparseSwitchPayload* payload =
242 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
243 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
244
245 const int32_t* keys = payload->GetKeys();
246 const int32_t* targets = payload->GetTargets();
247
248 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
249
250 llvm::SwitchInst* sw =
251 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
252 payload->case_count);
253
254 for (size_t i = 0; i < payload->case_count; ++i) {
255 llvm::BasicBlock* llvmBB =
256 findCaseTarget(cUnit, cUnit->currentDalvikOffset + targets[i]);
257 sw->addCase(cUnit->irb->getInt32(keys[i]), llvmBB);
258 }
259 llvm::MDNode* switchNode =
260 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
261 sw->setMetadata("SwitchTable", switchNode);
262 bb->taken = NULL;
263 bb->fallThrough = NULL;
264}
265
buzbee8fa0fda2012-06-27 15:44:52 -0700266void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
267 greenland::IntrinsicHelper::IntrinsicId id,
268 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700269{
buzbee8fa0fda2012-06-27 15:44:52 -0700270 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700271 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700272 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
273 defineValue(cUnit, res, rlDest.origSReg);
274}
275
276void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
277 greenland::IntrinsicHelper::IntrinsicId id,
278 RegLocation rlSrc)
279{
280 llvm::SmallVector<llvm::Value*, 2> args;
281 args.push_back(cUnit->irb->getInt32(fieldIndex));
282 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
283 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
284 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700285}
286
buzbee101305f2012-06-28 18:00:56 -0700287void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
288 RegLocation rlArray)
289{
290 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700291 id = greenland::IntrinsicHelper::HLFillArrayData;
buzbee101305f2012-06-28 18:00:56 -0700292 llvm::SmallVector<llvm::Value*, 2> args;
293 args.push_back(cUnit->irb->getInt32(offset));
294 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
295 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
296 cUnit->irb->CreateCall(intr, args);
297}
298
buzbee2cfc6392012-05-07 14:51:40 -0700299llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
300 RegLocation loc)
301{
302 greenland::IntrinsicHelper::IntrinsicId id;
303 if (loc.wide) {
304 if (loc.fp) {
305 id = greenland::IntrinsicHelper::ConstDouble;
306 } else {
307 id = greenland::IntrinsicHelper::ConstLong;
308 }
309 } else {
310 if (loc.fp) {
311 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700312 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700313 id = greenland::IntrinsicHelper::ConstObj;
314 } else {
315 id = greenland::IntrinsicHelper::ConstInt;
316 }
317 }
318 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
319 return cUnit->irb->CreateCall(intr, src);
320}
buzbeeb03f4872012-06-11 15:22:11 -0700321
322void emitPopShadowFrame(CompilationUnit* cUnit)
323{
324 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
325 greenland::IntrinsicHelper::PopShadowFrame);
326 cUnit->irb->CreateCall(intr);
327}
328
buzbee2cfc6392012-05-07 14:51:40 -0700329llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
330 RegLocation loc)
331{
332 greenland::IntrinsicHelper::IntrinsicId id;
333 if (loc.wide) {
334 if (loc.fp) {
335 id = greenland::IntrinsicHelper::CopyDouble;
336 } else {
337 id = greenland::IntrinsicHelper::CopyLong;
338 }
339 } else {
340 if (loc.fp) {
341 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700342 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700343 id = greenland::IntrinsicHelper::CopyObj;
344 } else {
345 id = greenland::IntrinsicHelper::CopyInt;
346 }
347 }
348 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
349 return cUnit->irb->CreateCall(intr, src);
350}
351
buzbee32412962012-06-26 16:27:56 -0700352void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
353{
354 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
355 greenland::IntrinsicHelper::GetException);
356 llvm::Value* res = cUnit->irb->CreateCall(func);
357 defineValue(cUnit, res, rlDest.origSReg);
358}
359
360void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
361{
362 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
363 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
TDYa127f71bf5a2012-07-29 20:09:52 -0700364 greenland::IntrinsicHelper::HLThrowException);
buzbee32412962012-06-26 16:27:56 -0700365 cUnit->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700366}
367
buzbee8fa0fda2012-06-27 15:44:52 -0700368void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
369 greenland::IntrinsicHelper::IntrinsicId id,
370 RegLocation rlSrc)
371{
372 llvm::SmallVector<llvm::Value*, 2> args;
373 args.push_back(cUnit->irb->getInt32(optFlags));
374 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
375 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
376 cUnit->irb->CreateCall(func, args);
377}
378
buzbee76592632012-06-29 15:18:35 -0700379void convertArrayLength(CompilationUnit* cUnit, int optFlags,
380 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700381{
382 llvm::SmallVector<llvm::Value*, 2> args;
383 args.push_back(cUnit->irb->getInt32(optFlags));
384 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
385 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700386 greenland::IntrinsicHelper::OptArrayLength);
buzbee76592632012-06-29 15:18:35 -0700387 llvm::Value* res = cUnit->irb->CreateCall(func, args);
388 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700389}
390
buzbee2cfc6392012-05-07 14:51:40 -0700391void emitSuspendCheck(CompilationUnit* cUnit)
392{
393 greenland::IntrinsicHelper::IntrinsicId id =
394 greenland::IntrinsicHelper::CheckSuspend;
395 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
396 cUnit->irb->CreateCall(intr);
397}
398
399llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
400 llvm::Value* src1, llvm::Value* src2)
401{
402 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700403 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700404 switch(cc) {
405 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
406 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
407 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
408 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
409 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
410 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
411 default: LOG(FATAL) << "Unexpected cc value " << cc;
412 }
413 return res;
414}
415
416void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
417 ConditionCode cc, RegLocation rlSrc1,
418 RegLocation rlSrc2)
419{
420 if (bb->taken->startOffset <= mir->offset) {
421 emitSuspendCheck(cUnit);
422 }
423 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
424 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
425 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
426 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
427 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
428 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700429 // Don't redo the fallthrough branch in the BB driver
430 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700431}
432
433void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
434 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
435{
436 if (bb->taken->startOffset <= mir->offset) {
437 emitSuspendCheck(cUnit);
438 }
439 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
440 llvm::Value* src2;
441 if (rlSrc1.ref) {
442 src2 = cUnit->irb->GetJNull();
443 } else {
444 src2 = cUnit->irb->getInt32(0);
445 }
446 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700447 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
448 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700449 // Don't redo the fallthrough branch in the BB driver
450 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700451}
452
453llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
454 llvm::Value* src1, llvm::Value* src2)
455{
456 greenland::IntrinsicHelper::IntrinsicId id;
457 if (isLong) {
458 if (isDiv) {
459 id = greenland::IntrinsicHelper::DivLong;
460 } else {
461 id = greenland::IntrinsicHelper::RemLong;
462 }
Logan Chien554e6072012-07-23 20:00:01 -0700463 } else {
464 if (isDiv) {
buzbee2cfc6392012-05-07 14:51:40 -0700465 id = greenland::IntrinsicHelper::DivInt;
466 } else {
467 id = greenland::IntrinsicHelper::RemInt;
Logan Chien554e6072012-07-23 20:00:01 -0700468 }
buzbee2cfc6392012-05-07 14:51:40 -0700469 }
470 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
471 llvm::SmallVector<llvm::Value*, 2>args;
472 args.push_back(src1);
473 args.push_back(src2);
474 return cUnit->irb->CreateCall(intr, args);
475}
476
477llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
478 llvm::Value* src1, llvm::Value* src2)
479{
480 llvm::Value* res = NULL;
481 switch(op) {
482 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
483 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700484 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700485 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
486 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
487 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
488 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
489 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
490 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700491 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
492 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
493 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700494 default:
495 LOG(FATAL) << "Invalid op " << op;
496 }
497 return res;
498}
499
500void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
501 RegLocation rlSrc1, RegLocation rlSrc2)
502{
503 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
504 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
505 llvm::Value* res = NULL;
506 switch(op) {
507 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
508 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
509 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
510 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
511 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
512 default:
513 LOG(FATAL) << "Invalid op " << op;
514 }
515 defineValue(cUnit, res, rlDest.origSReg);
516}
517
buzbee2a83e8f2012-07-13 16:42:30 -0700518void convertShift(CompilationUnit* cUnit,
519 greenland::IntrinsicHelper::IntrinsicId id,
520 RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
buzbee4f1181f2012-06-22 13:52:12 -0700521{
buzbee2a83e8f2012-07-13 16:42:30 -0700522 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
523 llvm::SmallVector<llvm::Value*, 2>args;
524 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
525 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
526 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
527 defineValue(cUnit, res, rlDest.origSReg);
528}
529
530void convertShiftLit(CompilationUnit* cUnit,
531 greenland::IntrinsicHelper::IntrinsicId id,
532 RegLocation rlDest, RegLocation rlSrc, int shiftAmount)
533{
534 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
535 llvm::SmallVector<llvm::Value*, 2>args;
536 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
537 args.push_back(cUnit->irb->getInt32(shiftAmount));
538 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700539 defineValue(cUnit, res, rlDest.origSReg);
540}
541
buzbee2cfc6392012-05-07 14:51:40 -0700542void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
543 RegLocation rlSrc1, RegLocation rlSrc2)
544{
545 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
546 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700547 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700548 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
549 defineValue(cUnit, res, rlDest.origSReg);
550}
551
buzbeeb03f4872012-06-11 15:22:11 -0700552void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
553{
554 int index = -1;
555 DCHECK(newVal != NULL);
556 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
557 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
558 if (cUnit->shadowMap[i] == vReg) {
559 index = i;
560 break;
561 }
562 }
TDYa127347166a2012-08-23 12:23:44 -0700563 if (index == -1) {
564 return;
565 }
buzbee6459e7c2012-10-02 14:42:41 -0700566 llvm::Type* ty = newVal->getType();
buzbeeb03f4872012-06-11 15:22:11 -0700567 greenland::IntrinsicHelper::IntrinsicId id =
568 greenland::IntrinsicHelper::SetShadowFrameEntry;
569 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
570 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
buzbee6459e7c2012-10-02 14:42:41 -0700571 // If newVal is a Null pointer, we'll see it here as a const int. Replace
572 if (!ty->isPointerTy()) {
573 // TODO: assert newVal created w/ dex_lang_const_int(0) or dex_lang_const_float(0)
574 newVal = cUnit->irb->GetJNull();
575 }
buzbeeb03f4872012-06-11 15:22:11 -0700576 llvm::Value* args[] = { newVal, tableSlot };
577 cUnit->irb->CreateCall(func, args);
578}
579
buzbee2cfc6392012-05-07 14:51:40 -0700580void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
581 RegLocation rlSrc1, int32_t imm)
582{
583 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
584 llvm::Value* src2 = cUnit->irb->getInt32(imm);
585 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
586 defineValue(cUnit, res, rlDest.origSReg);
587}
588
buzbee101305f2012-06-28 18:00:56 -0700589/*
590 * Process arguments for invoke. Note: this code is also used to
591 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
592 * The requirements are similar.
593 */
buzbee6969d502012-06-15 16:40:31 -0700594void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700595 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700596{
597 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
598 llvm::SmallVector<llvm::Value*, 10> args;
599 // Insert the invokeType
600 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
601 // Insert the method_idx
602 args.push_back(cUnit->irb->getInt32(info->index));
603 // Insert the optimization flags
604 args.push_back(cUnit->irb->getInt32(info->optFlags));
605 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700606 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700607 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
608 args.push_back(val);
609 i += info->args[i].wide ? 2 : 1;
610 }
611 /*
612 * Choose the invoke return type based on actual usage. Note: may
613 * be different than shorty. For example, if a function return value
614 * is not used, we'll treat this as a void invoke.
615 */
616 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700617 if (isFilledNewArray) {
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700618 id = greenland::IntrinsicHelper::HLFilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700619 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700620 id = greenland::IntrinsicHelper::HLInvokeVoid;
621 } else {
622 if (info->result.wide) {
623 if (info->result.fp) {
624 id = greenland::IntrinsicHelper::HLInvokeDouble;
625 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700626 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700627 }
628 } else if (info->result.ref) {
629 id = greenland::IntrinsicHelper::HLInvokeObj;
630 } else if (info->result.fp) {
631 id = greenland::IntrinsicHelper::HLInvokeFloat;
632 } else {
633 id = greenland::IntrinsicHelper::HLInvokeInt;
634 }
635 }
636 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
637 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
638 if (info->result.location != kLocInvalid) {
639 defineValue(cUnit, res, info->result.origSReg);
TDYa127890ea892012-08-22 10:49:42 -0700640 if (info->result.ref) {
641 setShadowFrameEntry(cUnit, (llvm::Value*)
642 cUnit->llvmValues.elemList[info->result.origSReg]);
643 }
buzbee6969d502012-06-15 16:40:31 -0700644 }
645}
646
buzbee101305f2012-06-28 18:00:56 -0700647void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
648 greenland::IntrinsicHelper::IntrinsicId id,
649 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700650{
buzbee6969d502012-06-15 16:40:31 -0700651 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700652 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700653 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
654 defineValue(cUnit, res, rlDest.origSReg);
655}
656
buzbee101305f2012-06-28 18:00:56 -0700657void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
658 RegLocation rlSrc)
659{
660 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700661 id = greenland::IntrinsicHelper::HLCheckCast;
buzbee101305f2012-06-28 18:00:56 -0700662 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
663 llvm::SmallVector<llvm::Value*, 2> args;
664 args.push_back(cUnit->irb->getInt32(type_idx));
665 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
666 cUnit->irb->CreateCall(intr, args);
667}
668
buzbee8fa0fda2012-06-27 15:44:52 -0700669void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
670 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700671{
672 greenland::IntrinsicHelper::IntrinsicId id;
673 id = greenland::IntrinsicHelper::NewInstance;
674 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
675 llvm::Value* index = cUnit->irb->getInt32(type_idx);
676 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
677 defineValue(cUnit, res, rlDest.origSReg);
678}
679
buzbee8fa0fda2012-06-27 15:44:52 -0700680void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
681 RegLocation rlDest, RegLocation rlSrc)
682{
683 greenland::IntrinsicHelper::IntrinsicId id;
684 id = greenland::IntrinsicHelper::NewArray;
685 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
686 llvm::SmallVector<llvm::Value*, 2> args;
687 args.push_back(cUnit->irb->getInt32(type_idx));
688 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
689 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
690 defineValue(cUnit, res, rlDest.origSReg);
691}
692
693void convertAget(CompilationUnit* cUnit, int optFlags,
694 greenland::IntrinsicHelper::IntrinsicId id,
695 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
696{
697 llvm::SmallVector<llvm::Value*, 3> args;
698 args.push_back(cUnit->irb->getInt32(optFlags));
699 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
700 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
701 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
702 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
703 defineValue(cUnit, res, rlDest.origSReg);
704}
705
706void convertAput(CompilationUnit* cUnit, int optFlags,
707 greenland::IntrinsicHelper::IntrinsicId id,
708 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
709{
710 llvm::SmallVector<llvm::Value*, 4> args;
711 args.push_back(cUnit->irb->getInt32(optFlags));
712 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
713 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
714 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
715 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
716 cUnit->irb->CreateCall(intr, args);
717}
718
buzbee101305f2012-06-28 18:00:56 -0700719void convertIget(CompilationUnit* cUnit, int optFlags,
720 greenland::IntrinsicHelper::IntrinsicId id,
721 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
722{
723 llvm::SmallVector<llvm::Value*, 3> args;
724 args.push_back(cUnit->irb->getInt32(optFlags));
725 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
726 args.push_back(cUnit->irb->getInt32(fieldIndex));
727 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
728 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
729 defineValue(cUnit, res, rlDest.origSReg);
730}
731
732void convertIput(CompilationUnit* cUnit, int optFlags,
733 greenland::IntrinsicHelper::IntrinsicId id,
734 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
735{
736 llvm::SmallVector<llvm::Value*, 4> args;
737 args.push_back(cUnit->irb->getInt32(optFlags));
738 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
739 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
740 args.push_back(cUnit->irb->getInt32(fieldIndex));
741 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
742 cUnit->irb->CreateCall(intr, args);
743}
744
buzbee8fa0fda2012-06-27 15:44:52 -0700745void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
746 RegLocation rlDest, RegLocation rlSrc)
747{
748 greenland::IntrinsicHelper::IntrinsicId id;
749 id = greenland::IntrinsicHelper::InstanceOf;
750 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
751 llvm::SmallVector<llvm::Value*, 2> args;
752 args.push_back(cUnit->irb->getInt32(type_idx));
753 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
754 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
755 defineValue(cUnit, res, rlDest.origSReg);
756}
757
buzbee101305f2012-06-28 18:00:56 -0700758void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
759 RegLocation rlSrc)
760{
761 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
762 cUnit->irb->getInt64Ty());
763 defineValue(cUnit, res, rlDest.origSReg);
764}
765
buzbee76592632012-06-29 15:18:35 -0700766void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
767 RegLocation rlSrc)
768{
769 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
770 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
771 defineValue(cUnit, res, rlDest.origSReg);
772}
773
774void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
775 RegLocation rlSrc)
776{
777 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
778 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
779 defineValue(cUnit, res, rlDest.origSReg);
780}
781
782void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
783 RegLocation rlSrc)
784{
785 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
786 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
787 defineValue(cUnit, res, rlDest.origSReg);
788}
789
790void convertWideComparison(CompilationUnit* cUnit,
791 greenland::IntrinsicHelper::IntrinsicId id,
792 RegLocation rlDest, RegLocation rlSrc1,
793 RegLocation rlSrc2)
794{
795 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
796 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
797 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
798 llvm::SmallVector<llvm::Value*, 2> args;
799 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
800 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
801 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
802 defineValue(cUnit, res, rlDest.origSReg);
803}
804
buzbee101305f2012-06-28 18:00:56 -0700805void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
806 RegLocation rlSrc,
807 greenland::IntrinsicHelper::IntrinsicId id)
808{
809 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700810 llvm::Value* res =
811 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
812 defineValue(cUnit, res, rlDest.origSReg);
813}
814
815void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
816 RegLocation rlSrc)
817{
818 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
819 defineValue(cUnit, res, rlDest.origSReg);
820}
821
822void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
823 RegLocation rlSrc)
824{
825 llvm::Value* res =
826 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
827 defineValue(cUnit, res, rlDest.origSReg);
828}
829
TDYa1274ec8ccd2012-08-11 07:04:57 -0700830void convertFPToInt(CompilationUnit* cUnit,
831 greenland::IntrinsicHelper::IntrinsicId id,
832 RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700833 RegLocation rlSrc)
834{
TDYa1274ec8ccd2012-08-11 07:04:57 -0700835 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
836 llvm::Value* res = cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
buzbee76592632012-06-29 15:18:35 -0700837 defineValue(cUnit, res, rlDest.origSReg);
838}
839
840
841void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
842 RegLocation rlSrc)
843{
844 llvm::Value* res =
845 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
846 defineValue(cUnit, res, rlDest.origSReg);
847}
848
849void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
850 RegLocation rlSrc)
851{
852 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
853 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700854 defineValue(cUnit, res, rlDest.origSReg);
855}
856
buzbee2cfc6392012-05-07 14:51:40 -0700857/*
858 * Target-independent code generation. Use only high-level
859 * load/store utilities here, or target-dependent genXX() handlers
860 * when necessary.
861 */
862bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
863 llvm::BasicBlock* llvmBB, LIR* labelList)
864{
865 bool res = false; // Assume success
866 RegLocation rlSrc[3];
867 RegLocation rlDest = badLoc;
buzbee2cfc6392012-05-07 14:51:40 -0700868 Instruction::Code opcode = mir->dalvikInsn.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) {
876 if ((int)opcode < kMirOpFirst) {
877 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x"
878 << std::hex << (int)opcode;
879 } else {
880 LOG(INFO) << ".. opcode 0x" << std::hex << (int)opcode;
881 }
882 }
883
buzbee2cfc6392012-05-07 14:51:40 -0700884 /* Prep Src and Dest locations */
885 int nextSreg = 0;
886 int nextLoc = 0;
887 int attrs = oatDataFlowAttributes[opcode];
888 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
889 if (attrs & DF_UA) {
890 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700891 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700892 nextSreg+= 2;
893 } else {
894 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
895 nextSreg++;
896 }
897 }
898 if (attrs & DF_UB) {
899 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700900 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700901 nextSreg+= 2;
902 } else {
903 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
904 nextSreg++;
905 }
906 }
907 if (attrs & DF_UC) {
908 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700909 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700910 } else {
911 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
912 }
913 }
914 if (attrs & DF_DA) {
915 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700916 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700917 } else {
buzbee15bf9802012-06-12 17:49:27 -0700918 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700919 if (rlDest.ref) {
920 objectDefinition = true;
921 }
buzbee2cfc6392012-05-07 14:51:40 -0700922 }
923 }
924
925 switch (opcode) {
926 case Instruction::NOP:
927 break;
928
929 case Instruction::MOVE:
930 case Instruction::MOVE_OBJECT:
931 case Instruction::MOVE_16:
932 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700933 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700934 case Instruction::MOVE_FROM16:
935 case Instruction::MOVE_WIDE:
936 case Instruction::MOVE_WIDE_16:
937 case Instruction::MOVE_WIDE_FROM16: {
938 /*
939 * Moves/copies are meaningless in pure SSA register form,
940 * but we need to preserve them for the conversion back into
941 * MIR (at least until we stop using the Dalvik register maps).
942 * Insert a dummy intrinsic copy call, which will be recognized
943 * by the quick path and removed by the portable path.
944 */
945 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
946 llvm::Value* res = emitCopy(cUnit, src, rlDest);
947 defineValue(cUnit, res, rlDest.origSReg);
948 }
949 break;
950
951 case Instruction::CONST:
952 case Instruction::CONST_4:
953 case Instruction::CONST_16: {
TDYa127347166a2012-08-23 12:23:44 -0700954 if (vB == 0) {
955 objectDefinition = true;
956 }
buzbee6969d502012-06-15 16:40:31 -0700957 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700958 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
959 defineValue(cUnit, res, rlDest.origSReg);
960 }
961 break;
962
963 case Instruction::CONST_WIDE_16:
964 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700965 // Sign extend to 64 bits
966 int64_t imm = static_cast<int32_t>(vB);
967 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700968 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
969 defineValue(cUnit, res, rlDest.origSReg);
970 }
971 break;
972
973 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700974 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700975 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
976 defineValue(cUnit, res, rlDest.origSReg);
977 }
978 break;
979
980 case Instruction::CONST_WIDE: {
981 llvm::Constant* immValue =
982 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
983 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
984 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700985 }
986 break;
buzbee2cfc6392012-05-07 14:51:40 -0700987 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700988 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700989 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
990 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
991 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700992 }
993 break;
994
buzbee8fa0fda2012-06-27 15:44:52 -0700995 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700996 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700997 rlSrc[0]);
998 break;
999 case Instruction::SPUT:
1000 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -07001001 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -07001002 rlSrc[0]);
1003 } else {
buzbee76592632012-06-29 15:18:35 -07001004 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001005 }
1006 break;
1007 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -07001008 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -07001009 rlSrc[0]);
1010 break;
1011 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -07001012 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001013 break;
1014 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -07001015 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001016 break;
1017 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -07001018 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001019 break;
1020 case Instruction::SPUT_WIDE:
1021 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -07001022 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -07001023 rlSrc[0]);
1024 } else {
buzbee76592632012-06-29 15:18:35 -07001025 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -07001026 rlSrc[0]);
1027 }
1028 break;
1029
1030 case Instruction::SGET_OBJECT:
1031 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
1032 break;
1033 case Instruction::SGET:
1034 if (rlDest.fp) {
1035 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
1036 } else {
1037 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
1038 }
1039 break;
1040 case Instruction::SGET_BOOLEAN:
1041 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
1042 break;
1043 case Instruction::SGET_BYTE:
1044 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
1045 break;
1046 case Instruction::SGET_CHAR:
1047 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
1048 break;
1049 case Instruction::SGET_SHORT:
1050 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
1051 break;
1052 case Instruction::SGET_WIDE:
1053 if (rlDest.fp) {
1054 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
1055 rlDest);
1056 } else {
1057 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001058 }
1059 break;
buzbee2cfc6392012-05-07 14:51:40 -07001060
1061 case Instruction::RETURN_WIDE:
1062 case Instruction::RETURN:
1063 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -07001064 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001065 emitSuspendCheck(cUnit);
1066 }
buzbeeb03f4872012-06-11 15:22:11 -07001067 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001068 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
1069 bb->hasReturn = true;
1070 }
1071 break;
1072
1073 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001074 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001075 emitSuspendCheck(cUnit);
1076 }
buzbeeb03f4872012-06-11 15:22:11 -07001077 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001078 cUnit->irb->CreateRetVoid();
1079 bb->hasReturn = true;
1080 }
1081 break;
1082
1083 case Instruction::IF_EQ:
1084 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1085 break;
1086 case Instruction::IF_NE:
1087 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1088 break;
1089 case Instruction::IF_LT:
1090 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1091 break;
1092 case Instruction::IF_GE:
1093 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1094 break;
1095 case Instruction::IF_GT:
1096 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1097 break;
1098 case Instruction::IF_LE:
1099 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1100 break;
1101 case Instruction::IF_EQZ:
1102 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1103 break;
1104 case Instruction::IF_NEZ:
1105 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1106 break;
1107 case Instruction::IF_LTZ:
1108 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1109 break;
1110 case Instruction::IF_GEZ:
1111 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1112 break;
1113 case Instruction::IF_GTZ:
1114 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1115 break;
1116 case Instruction::IF_LEZ:
1117 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1118 break;
1119
1120 case Instruction::GOTO:
1121 case Instruction::GOTO_16:
1122 case Instruction::GOTO_32: {
1123 if (bb->taken->startOffset <= bb->startOffset) {
1124 emitSuspendCheck(cUnit);
1125 }
1126 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1127 }
1128 break;
1129
1130 case Instruction::ADD_LONG:
1131 case Instruction::ADD_LONG_2ADDR:
1132 case Instruction::ADD_INT:
1133 case Instruction::ADD_INT_2ADDR:
1134 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1135 break;
1136 case Instruction::SUB_LONG:
1137 case Instruction::SUB_LONG_2ADDR:
1138 case Instruction::SUB_INT:
1139 case Instruction::SUB_INT_2ADDR:
1140 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1141 break;
1142 case Instruction::MUL_LONG:
1143 case Instruction::MUL_LONG_2ADDR:
1144 case Instruction::MUL_INT:
1145 case Instruction::MUL_INT_2ADDR:
1146 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1147 break;
1148 case Instruction::DIV_LONG:
1149 case Instruction::DIV_LONG_2ADDR:
1150 case Instruction::DIV_INT:
1151 case Instruction::DIV_INT_2ADDR:
1152 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1153 break;
1154 case Instruction::REM_LONG:
1155 case Instruction::REM_LONG_2ADDR:
1156 case Instruction::REM_INT:
1157 case Instruction::REM_INT_2ADDR:
1158 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1159 break;
1160 case Instruction::AND_LONG:
1161 case Instruction::AND_LONG_2ADDR:
1162 case Instruction::AND_INT:
1163 case Instruction::AND_INT_2ADDR:
1164 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1165 break;
1166 case Instruction::OR_LONG:
1167 case Instruction::OR_LONG_2ADDR:
1168 case Instruction::OR_INT:
1169 case Instruction::OR_INT_2ADDR:
1170 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1171 break;
1172 case Instruction::XOR_LONG:
1173 case Instruction::XOR_LONG_2ADDR:
1174 case Instruction::XOR_INT:
1175 case Instruction::XOR_INT_2ADDR:
1176 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1177 break;
1178 case Instruction::SHL_LONG:
1179 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001180 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1181 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001182 break;
buzbee2cfc6392012-05-07 14:51:40 -07001183 case Instruction::SHL_INT:
1184 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001185 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1186 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001187 break;
1188 case Instruction::SHR_LONG:
1189 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001190 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1191 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001192 break;
buzbee2cfc6392012-05-07 14:51:40 -07001193 case Instruction::SHR_INT:
1194 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001195 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1196 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001197 break;
1198 case Instruction::USHR_LONG:
1199 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001200 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1201 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001202 break;
buzbee2cfc6392012-05-07 14:51:40 -07001203 case Instruction::USHR_INT:
1204 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001205 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1206 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001207 break;
1208
1209 case Instruction::ADD_INT_LIT16:
1210 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001211 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001212 break;
1213 case Instruction::RSUB_INT:
1214 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001215 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001216 break;
1217 case Instruction::MUL_INT_LIT16:
1218 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001219 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001220 break;
1221 case Instruction::DIV_INT_LIT16:
1222 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001223 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001224 break;
1225 case Instruction::REM_INT_LIT16:
1226 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001227 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001228 break;
1229 case Instruction::AND_INT_LIT16:
1230 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001231 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001232 break;
1233 case Instruction::OR_INT_LIT16:
1234 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001235 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001236 break;
1237 case Instruction::XOR_INT_LIT16:
1238 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001239 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001240 break;
1241 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001242 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1243 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001244 break;
1245 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001246 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1247 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001248 break;
1249 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001250 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1251 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001252 break;
1253
1254 case Instruction::ADD_FLOAT:
1255 case Instruction::ADD_FLOAT_2ADDR:
1256 case Instruction::ADD_DOUBLE:
1257 case Instruction::ADD_DOUBLE_2ADDR:
1258 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1259 break;
1260
1261 case Instruction::SUB_FLOAT:
1262 case Instruction::SUB_FLOAT_2ADDR:
1263 case Instruction::SUB_DOUBLE:
1264 case Instruction::SUB_DOUBLE_2ADDR:
1265 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1266 break;
1267
1268 case Instruction::MUL_FLOAT:
1269 case Instruction::MUL_FLOAT_2ADDR:
1270 case Instruction::MUL_DOUBLE:
1271 case Instruction::MUL_DOUBLE_2ADDR:
1272 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1273 break;
1274
1275 case Instruction::DIV_FLOAT:
1276 case Instruction::DIV_FLOAT_2ADDR:
1277 case Instruction::DIV_DOUBLE:
1278 case Instruction::DIV_DOUBLE_2ADDR:
1279 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1280 break;
1281
1282 case Instruction::REM_FLOAT:
1283 case Instruction::REM_FLOAT_2ADDR:
1284 case Instruction::REM_DOUBLE:
1285 case Instruction::REM_DOUBLE_2ADDR:
1286 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1287 break;
1288
buzbee6969d502012-06-15 16:40:31 -07001289 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001290 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1291 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001292 break;
1293 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001294 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1295 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001296 break;
1297
1298 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001299 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1300 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001301 break;
1302 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001303 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1304 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001305 break;
1306
1307 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001308 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1309 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001310 break;
1311 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001312 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1313 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001314 break;
1315
1316 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001317 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1318 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001319 break;
1320 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001321 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1322 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001323 break;
1324
1325 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001326 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1327 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001328 break;
1329 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001330 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1331 false /* NewFilledArray */);
1332 break;
1333 case Instruction::FILLED_NEW_ARRAY:
1334 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1335 true /* NewFilledArray */);
1336 break;
1337 case Instruction::FILLED_NEW_ARRAY_RANGE:
1338 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1339 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001340 break;
1341
1342 case Instruction::CONST_STRING:
1343 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001344 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1345 rlDest);
1346 break;
1347
1348 case Instruction::CONST_CLASS:
1349 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1350 rlDest);
1351 break;
1352
1353 case Instruction::CHECK_CAST:
1354 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001355 break;
1356
buzbee4f1181f2012-06-22 13:52:12 -07001357 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001358 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001359 break;
1360
buzbee32412962012-06-26 16:27:56 -07001361 case Instruction::MOVE_EXCEPTION:
1362 convertMoveException(cUnit, rlDest);
1363 break;
1364
1365 case Instruction::THROW:
1366 convertThrow(cUnit, rlSrc[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001367 /*
1368 * If this throw is standalone, terminate.
1369 * If it might rethrow, force termination
1370 * of the following block.
1371 */
1372 if (bb->fallThrough == NULL) {
1373 cUnit->irb->CreateUnreachable();
1374 } else {
1375 bb->fallThrough->fallThrough = NULL;
1376 bb->fallThrough->taken = NULL;
1377 }
buzbee32412962012-06-26 16:27:56 -07001378 break;
1379
buzbee2cfc6392012-05-07 14:51:40 -07001380 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001381 case Instruction::MOVE_RESULT:
1382 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001383 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001384 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001385 */
jeffhao9a4f0032012-08-30 16:17:40 -07001386 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001387 break;
1388
1389 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001390 convertMonitorEnterExit(cUnit, optFlags,
1391 greenland::IntrinsicHelper::MonitorEnter,
1392 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001393 break;
1394
1395 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001396 convertMonitorEnterExit(cUnit, optFlags,
1397 greenland::IntrinsicHelper::MonitorExit,
1398 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001399 break;
1400
1401 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001402 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001403 break;
1404
1405 case Instruction::NEW_ARRAY:
1406 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1407 break;
1408
1409 case Instruction::INSTANCE_OF:
1410 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1411 break;
1412
1413 case Instruction::AGET:
1414 if (rlDest.fp) {
1415 convertAget(cUnit, optFlags,
1416 greenland::IntrinsicHelper::HLArrayGetFloat,
1417 rlDest, rlSrc[0], rlSrc[1]);
1418 } else {
1419 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1420 rlDest, rlSrc[0], rlSrc[1]);
1421 }
1422 break;
1423 case Instruction::AGET_OBJECT:
1424 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1425 rlDest, rlSrc[0], rlSrc[1]);
1426 break;
1427 case Instruction::AGET_BOOLEAN:
1428 convertAget(cUnit, optFlags,
1429 greenland::IntrinsicHelper::HLArrayGetBoolean,
1430 rlDest, rlSrc[0], rlSrc[1]);
1431 break;
1432 case Instruction::AGET_BYTE:
1433 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1434 rlDest, rlSrc[0], rlSrc[1]);
1435 break;
1436 case Instruction::AGET_CHAR:
1437 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1438 rlDest, rlSrc[0], rlSrc[1]);
1439 break;
1440 case Instruction::AGET_SHORT:
1441 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1442 rlDest, rlSrc[0], rlSrc[1]);
1443 break;
1444 case Instruction::AGET_WIDE:
1445 if (rlDest.fp) {
1446 convertAget(cUnit, optFlags,
1447 greenland::IntrinsicHelper::HLArrayGetDouble,
1448 rlDest, rlSrc[0], rlSrc[1]);
1449 } else {
1450 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1451 rlDest, rlSrc[0], rlSrc[1]);
1452 }
1453 break;
1454
1455 case Instruction::APUT:
1456 if (rlSrc[0].fp) {
1457 convertAput(cUnit, optFlags,
1458 greenland::IntrinsicHelper::HLArrayPutFloat,
1459 rlSrc[0], rlSrc[1], rlSrc[2]);
1460 } else {
1461 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1462 rlSrc[0], rlSrc[1], rlSrc[2]);
1463 }
1464 break;
1465 case Instruction::APUT_OBJECT:
1466 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1467 rlSrc[0], rlSrc[1], rlSrc[2]);
1468 break;
1469 case Instruction::APUT_BOOLEAN:
1470 convertAput(cUnit, optFlags,
1471 greenland::IntrinsicHelper::HLArrayPutBoolean,
1472 rlSrc[0], rlSrc[1], rlSrc[2]);
1473 break;
1474 case Instruction::APUT_BYTE:
1475 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1476 rlSrc[0], rlSrc[1], rlSrc[2]);
1477 break;
1478 case Instruction::APUT_CHAR:
1479 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1480 rlSrc[0], rlSrc[1], rlSrc[2]);
1481 break;
1482 case Instruction::APUT_SHORT:
1483 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1484 rlSrc[0], rlSrc[1], rlSrc[2]);
1485 break;
1486 case Instruction::APUT_WIDE:
1487 if (rlSrc[0].fp) {
1488 convertAput(cUnit, optFlags,
1489 greenland::IntrinsicHelper::HLArrayPutDouble,
1490 rlSrc[0], rlSrc[1], rlSrc[2]);
1491 } else {
1492 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1493 rlSrc[0], rlSrc[1], rlSrc[2]);
1494 }
1495 break;
1496
buzbee101305f2012-06-28 18:00:56 -07001497 case Instruction::IGET:
1498 if (rlDest.fp) {
1499 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001500 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001501 } else {
1502 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001503 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001504 }
buzbee2cfc6392012-05-07 14:51:40 -07001505 break;
buzbee101305f2012-06-28 18:00:56 -07001506 case Instruction::IGET_OBJECT:
1507 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001508 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001509 break;
1510 case Instruction::IGET_BOOLEAN:
1511 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001512 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001513 break;
1514 case Instruction::IGET_BYTE:
1515 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001516 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001517 break;
1518 case Instruction::IGET_CHAR:
1519 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001520 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001521 break;
1522 case Instruction::IGET_SHORT:
1523 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001524 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001525 break;
1526 case Instruction::IGET_WIDE:
1527 if (rlDest.fp) {
1528 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001529 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001530 } else {
1531 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001532 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001533 }
1534 break;
1535 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001536 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001537 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1538 rlSrc[0], rlSrc[1], vC);
1539 } else {
1540 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1541 rlSrc[0], rlSrc[1], vC);
1542 }
1543 break;
1544 case Instruction::IPUT_OBJECT:
1545 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1546 rlSrc[0], rlSrc[1], vC);
1547 break;
1548 case Instruction::IPUT_BOOLEAN:
1549 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1550 rlSrc[0], rlSrc[1], vC);
1551 break;
1552 case Instruction::IPUT_BYTE:
1553 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1554 rlSrc[0], rlSrc[1], vC);
1555 break;
1556 case Instruction::IPUT_CHAR:
1557 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1558 rlSrc[0], rlSrc[1], vC);
1559 break;
1560 case Instruction::IPUT_SHORT:
1561 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1562 rlSrc[0], rlSrc[1], vC);
1563 break;
1564 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001565 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001566 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1567 rlSrc[0], rlSrc[1], vC);
1568 } else {
1569 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1570 rlSrc[0], rlSrc[1], vC);
1571 }
buzbee2cfc6392012-05-07 14:51:40 -07001572 break;
1573
1574 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001575 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001576 break;
1577
buzbee76592632012-06-29 15:18:35 -07001578 case Instruction::LONG_TO_INT:
1579 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1580 break;
1581
buzbee101305f2012-06-28 18:00:56 -07001582 case Instruction::INT_TO_LONG:
1583 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001584 break;
1585
buzbee101305f2012-06-28 18:00:56 -07001586 case Instruction::INT_TO_CHAR:
1587 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1588 greenland::IntrinsicHelper::IntToChar);
1589 break;
1590 case Instruction::INT_TO_BYTE:
1591 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1592 greenland::IntrinsicHelper::IntToByte);
1593 break;
1594 case Instruction::INT_TO_SHORT:
1595 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1596 greenland::IntrinsicHelper::IntToShort);
1597 break;
1598
buzbee76592632012-06-29 15:18:35 -07001599 case Instruction::INT_TO_FLOAT:
1600 case Instruction::LONG_TO_FLOAT:
1601 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001602 break;
1603
buzbee76592632012-06-29 15:18:35 -07001604 case Instruction::INT_TO_DOUBLE:
1605 case Instruction::LONG_TO_DOUBLE:
1606 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001607 break;
1608
buzbee76592632012-06-29 15:18:35 -07001609 case Instruction::FLOAT_TO_DOUBLE:
1610 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001611 break;
1612
buzbee76592632012-06-29 15:18:35 -07001613 case Instruction::DOUBLE_TO_FLOAT:
1614 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001615 break;
1616
1617 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001618 case Instruction::NEG_INT:
1619 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001620 break;
1621
1622 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001623 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001624 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001625 break;
1626
buzbee76592632012-06-29 15:18:35 -07001627 case Instruction::NOT_LONG:
1628 case Instruction::NOT_INT:
1629 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001630 break;
1631
buzbee2cfc6392012-05-07 14:51:40 -07001632 case Instruction::FLOAT_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001633 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2I, rlDest, rlSrc[0]);
1634 break;
1635
buzbee2cfc6392012-05-07 14:51:40 -07001636 case Instruction::DOUBLE_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001637 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2I, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001638 break;
1639
buzbee76592632012-06-29 15:18:35 -07001640 case Instruction::FLOAT_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001641 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2L, rlDest, rlSrc[0]);
1642 break;
1643
buzbee76592632012-06-29 15:18:35 -07001644 case Instruction::DOUBLE_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001645 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2L, rlDest, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001646 break;
1647
1648 case Instruction::CMPL_FLOAT:
1649 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1650 rlDest, rlSrc[0], rlSrc[1]);
1651 break;
1652 case Instruction::CMPG_FLOAT:
1653 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1654 rlDest, rlSrc[0], rlSrc[1]);
1655 break;
1656 case Instruction::CMPL_DOUBLE:
1657 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1658 rlDest, rlSrc[0], rlSrc[1]);
1659 break;
1660 case Instruction::CMPG_DOUBLE:
1661 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1662 rlDest, rlSrc[0], rlSrc[1]);
1663 break;
1664 case Instruction::CMP_LONG:
1665 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1666 rlDest, rlSrc[0], rlSrc[1]);
1667 break;
1668
buzbee76592632012-06-29 15:18:35 -07001669 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001670 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001671 break;
1672
1673 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001674 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001675 break;
buzbee2cfc6392012-05-07 14:51:40 -07001676
1677 default:
buzbee32412962012-06-26 16:27:56 -07001678 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001679 res = true;
1680 }
buzbeeb03f4872012-06-11 15:22:11 -07001681 if (objectDefinition) {
1682 setShadowFrameEntry(cUnit, (llvm::Value*)
1683 cUnit->llvmValues.elemList[rlDest.origSReg]);
1684 }
buzbee2cfc6392012-05-07 14:51:40 -07001685 return res;
1686}
1687
1688/* Extended MIR instructions like PHI */
1689void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1690 llvm::BasicBlock* llvmBB)
1691{
1692
1693 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1694 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001695 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001696 /*
1697 * The Art compiler's Phi nodes only handle 32-bit operands,
1698 * representing wide values using a matched set of Phi nodes
1699 * for the lower and upper halves. In the llvm world, we only
1700 * want a single Phi for wides. Here we will simply discard
1701 * the Phi node representing the high word.
1702 */
1703 if (rlDest.highWord) {
1704 return; // No Phi node - handled via low word
1705 }
1706 int* incoming = (int*)mir->dalvikInsn.vB;
buzbee2cfc6392012-05-07 14:51:40 -07001707 llvm::Type* phiType =
1708 llvmTypeFromLocRec(cUnit, rlDest);
1709 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1710 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1711 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001712 // Don't check width here.
1713 loc = oatGetRawSrc(cUnit, mir, i);
1714 DCHECK_EQ(rlDest.wide, loc.wide);
1715 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1716 DCHECK_EQ(rlDest.fp, loc.fp);
1717 DCHECK_EQ(rlDest.core, loc.core);
1718 DCHECK_EQ(rlDest.ref, loc.ref);
buzbeed1643e42012-09-05 14:06:51 -07001719 SafeMap<unsigned int, unsigned int>::iterator it;
1720 it = cUnit->blockIdMap.find(incoming[i]);
1721 DCHECK(it != cUnit->blockIdMap.end());
buzbee2cfc6392012-05-07 14:51:40 -07001722 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
buzbeed1643e42012-09-05 14:06:51 -07001723 getLLVMBlock(cUnit, it->second));
buzbee2cfc6392012-05-07 14:51:40 -07001724 }
1725 defineValue(cUnit, phi, rlDest.origSReg);
1726 break;
1727 }
1728 case kMirOpCopy: {
1729 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1730 break;
1731 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001732 case kMirOpNop:
1733 if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
1734 (bb->fallThrough == NULL)) {
1735 cUnit->irb->CreateUnreachable();
1736 }
1737 break;
1738
buzbeeb046e162012-10-30 15:48:42 -07001739 // TODO: need GBC intrinsic to take advantage of fused operations
buzbee2cfc6392012-05-07 14:51:40 -07001740 case kMirOpFusedCmplFloat:
buzbeeb046e162012-10-30 15:48:42 -07001741 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpFloat unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001742 break;
1743 case kMirOpFusedCmpgFloat:
buzbeeb046e162012-10-30 15:48:42 -07001744 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmgFloat unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001745 break;
1746 case kMirOpFusedCmplDouble:
buzbeeb046e162012-10-30 15:48:42 -07001747 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmplDouble unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001748 break;
1749 case kMirOpFusedCmpgDouble:
buzbeeb046e162012-10-30 15:48:42 -07001750 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpgDouble unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001751 break;
1752 case kMirOpFusedCmpLong:
buzbeeb046e162012-10-30 15:48:42 -07001753 UNIMPLEMENTED(FATAL) << "kMirOpLongCmpBranch unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001754 break;
buzbee2cfc6392012-05-07 14:51:40 -07001755 default:
1756 break;
1757 }
1758}
1759
1760void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1761{
1762 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001763 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001764 arrayRef.push_back(cUnit->irb->getInt32(offset));
1765 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1766 cUnit->irb->SetDexOffset(node);
1767}
1768
1769// Attach method info as metadata to special intrinsic
1770void setMethodInfo(CompilationUnit* cUnit)
1771{
1772 // We don't want dex offset on this
1773 cUnit->irb->SetDexOffset(NULL);
1774 greenland::IntrinsicHelper::IntrinsicId id;
1775 id = greenland::IntrinsicHelper::MethodInfo;
1776 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1777 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1778 llvm::SmallVector<llvm::Value*, 2> regInfo;
1779 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1780 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1781 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1782 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1783 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1784 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1785 inst->setMetadata("RegInfo", regInfoNode);
1786 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1787 llvm::SmallVector<llvm::Value*, 50> pmap;
1788 for (int i = 0; i < promoSize; i++) {
1789 PromotionMap* p = &cUnit->promotionMap[i];
1790 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1791 ((p->fpReg & 0xff) << 16) |
1792 ((p->coreReg & 0xff) << 8) |
1793 ((p->fpLocation & 0xf) << 4) |
1794 (p->coreLocation & 0xf);
1795 pmap.push_back(cUnit->irb->getInt32(mapData));
1796 }
1797 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1798 inst->setMetadata("PromotionMap", mapNode);
1799 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1800}
1801
1802/* Handle the content in each basic block */
1803bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1804{
buzbeed1643e42012-09-05 14:06:51 -07001805 if (bb->blockType == kDead) return false;
buzbee2cfc6392012-05-07 14:51:40 -07001806 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
buzbeef5f5a122012-09-21 13:57:36 -07001807 if (llvmBB == NULL) {
1808 CHECK(bb->blockType == kExitBlock);
1809 } else {
1810 cUnit->irb->SetInsertPoint(llvmBB);
1811 setDexOffset(cUnit, bb->startOffset);
1812 }
buzbee2cfc6392012-05-07 14:51:40 -07001813
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001814 if (cUnit->printMe) {
1815 LOG(INFO) << "................................";
1816 LOG(INFO) << "Block id " << bb->id;
1817 if (llvmBB != NULL) {
1818 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1819 } else {
1820 LOG(INFO) << "llvmBB is NULL";
1821 }
1822 }
1823
buzbee2cfc6392012-05-07 14:51:40 -07001824 if (bb->blockType == kEntryBlock) {
1825 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001826 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1827 cUnit->numDalvikRegisters, true,
1828 kAllocMisc);
1829 for (int i = 0; i < cUnit->numSSARegs; i++) {
buzbee6ec5e232012-09-20 15:50:03 -07001830 int vReg = SRegToVReg(cUnit, i);
1831 if (vReg > SSA_METHOD_BASEREG) {
1832 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1833 }
buzbeeb03f4872012-06-11 15:22:11 -07001834 }
1835 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1836 if (canBeRef[i]) {
1837 cUnit->numShadowFrameEntries++;
1838 }
1839 }
1840 if (cUnit->numShadowFrameEntries > 0) {
1841 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1842 cUnit->numShadowFrameEntries, true,
1843 kAllocMisc);
1844 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1845 if (canBeRef[i]) {
1846 cUnit->shadowMap[j++] = i;
1847 }
1848 }
buzbeeb03f4872012-06-11 15:22:11 -07001849 }
Shih-wei Liao569daf12012-08-10 23:22:33 -07001850 greenland::IntrinsicHelper::IntrinsicId id =
1851 greenland::IntrinsicHelper::AllocaShadowFrame;
1852 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1853 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
TDYa1278e950c12012-11-02 09:58:19 -07001854 llvm::Value* dalvikRegs = cUnit->irb->getInt32(cUnit->numDalvikRegisters);
1855 llvm::Value* args[] = { entries, dalvikRegs };
1856 cUnit->irb->CreateCall(func, args);
buzbee2cfc6392012-05-07 14:51:40 -07001857 } else if (bb->blockType == kExitBlock) {
1858 /*
1859 * Because of the differences between how MIR/LIR and llvm handle exit
1860 * blocks, we won't explicitly covert them. On the llvm-to-lir
1861 * path, it will need to be regenereated.
1862 */
1863 return false;
buzbee6969d502012-06-15 16:40:31 -07001864 } else if (bb->blockType == kExceptionHandling) {
1865 /*
1866 * Because we're deferring null checking, delete the associated empty
1867 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001868 */
1869 llvmBB->eraseFromParent();
1870 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001871 }
1872
1873 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1874
1875 setDexOffset(cUnit, mir->offset);
1876
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001877 int opcode = mir->dalvikInsn.opcode;
1878 Instruction::Format dalvikFormat =
1879 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001880
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001881 if (opcode == kMirOpCheck) {
1882 // Combine check and work halves of throwing instruction.
1883 MIR* workHalf = mir->meta.throwInsn;
1884 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
1885 opcode = mir->dalvikInsn.opcode;
1886 SSARepresentation* ssaRep = workHalf->ssaRep;
1887 workHalf->ssaRep = mir->ssaRep;
1888 mir->ssaRep = ssaRep;
1889 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1890 if (bb->successorBlockList.blockListType == kCatch) {
1891 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
1892 greenland::IntrinsicHelper::CatchTargets);
1893 llvm::Value* switchKey =
1894 cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
1895 GrowableListIterator iter;
1896 oatGrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
1897 // New basic block to use for work half
1898 llvm::BasicBlock* workBB =
1899 llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
1900 llvm::SwitchInst* sw =
1901 cUnit->irb->CreateSwitch(switchKey, workBB,
1902 bb->successorBlockList.blocks.numUsed);
1903 while (true) {
1904 SuccessorBlockInfo *successorBlockInfo =
1905 (SuccessorBlockInfo *) oatGrowableListIteratorNext(&iter);
1906 if (successorBlockInfo == NULL) break;
1907 llvm::BasicBlock *target =
1908 getLLVMBlock(cUnit, successorBlockInfo->block->id);
1909 int typeIndex = successorBlockInfo->key;
1910 sw->addCase(cUnit->irb->getInt32(typeIndex), target);
1911 }
1912 llvmBB = workBB;
1913 cUnit->irb->SetInsertPoint(llvmBB);
1914 }
1915 }
1916
1917 if (opcode >= kMirOpFirst) {
buzbee2cfc6392012-05-07 14:51:40 -07001918 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1919 continue;
1920 }
1921
1922 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1923 NULL /* labelList */);
1924 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001925 Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001926 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001927 mir->offset, opcode,
buzbee2cfc6392012-05-07 14:51:40 -07001928 Instruction::Name(dalvikOpcode),
1929 dalvikFormat);
1930 }
1931 }
1932
buzbee4be777b2012-07-12 14:38:18 -07001933 if (bb->blockType == kEntryBlock) {
1934 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1935 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001936 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1937 }
1938
1939 return false;
1940}
1941
buzbee4f4dfc72012-07-02 14:54:44 -07001942char remapShorty(char shortyType) {
1943 /*
1944 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1945 * and longs/doubles are represented as a pair of registers. When sub-word
1946 * arguments (and method results) are passed, they are extended to Dalvik
1947 * virtual register containers. Because llvm is picky about type consistency,
1948 * we must either cast the "real" type to 32-bit container multiple Dalvik
1949 * register types, or always use the expanded values.
1950 * Here, we're doing the latter. We map the shorty signature to container
1951 * types (which is valid so long as we always do a real expansion of passed
1952 * arguments and field loads).
1953 */
1954 switch(shortyType) {
1955 case 'Z' : shortyType = 'I'; break;
1956 case 'B' : shortyType = 'I'; break;
1957 case 'S' : shortyType = 'I'; break;
1958 case 'C' : shortyType = 'I'; break;
1959 default: break;
1960 }
1961 return shortyType;
1962}
1963
buzbee2cfc6392012-05-07 14:51:40 -07001964llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1965
1966 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001967 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001968 greenland::kAccurate);
1969
1970 // Get argument type
1971 std::vector<llvm::Type*> args_type;
1972
1973 // method object
1974 args_type.push_back(cUnit->irb->GetJMethodTy());
1975
1976 // Do we have a "this"?
1977 if ((cUnit->access_flags & kAccStatic) == 0) {
1978 args_type.push_back(cUnit->irb->GetJObjectTy());
1979 }
1980
1981 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001982 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001983 greenland::kAccurate));
1984 }
1985
1986 return llvm::FunctionType::get(ret_type, args_type, false);
1987}
1988
1989bool createFunction(CompilationUnit* cUnit) {
1990 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1991 /* with_signature */ false));
1992 llvm::FunctionType* func_type = getFunctionType(cUnit);
1993
1994 if (func_type == NULL) {
1995 return false;
1996 }
1997
1998 cUnit->func = llvm::Function::Create(func_type,
1999 llvm::Function::ExternalLinkage,
2000 func_name, cUnit->module);
2001
2002 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2003 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
2004
2005 arg_iter->setName("method");
2006 ++arg_iter;
2007
2008 int startSReg = cUnit->numRegs;
2009
2010 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
2011 arg_iter->setName(StringPrintf("v%i_0", startSReg));
2012 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
2013 }
2014
2015 return true;
2016}
2017
2018bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
2019{
2020 // Skip the exit block
buzbeed1643e42012-09-05 14:06:51 -07002021 if ((bb->blockType == kDead) ||(bb->blockType == kExitBlock)) {
buzbee2cfc6392012-05-07 14:51:40 -07002022 cUnit->idToBlockMap.Put(bb->id, NULL);
2023 } else {
2024 int offset = bb->startOffset;
2025 bool entryBlock = (bb->blockType == kEntryBlock);
2026 llvm::BasicBlock* llvmBB =
2027 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
buzbee8320f382012-09-11 16:29:42 -07002028 StringPrintf(kLabelFormat, bb->catchEntry ? kCatchBlock :
2029 kNormalBlock, offset, bb->id), cUnit->func);
buzbee2cfc6392012-05-07 14:51:40 -07002030 if (entryBlock) {
2031 cUnit->entryBB = llvmBB;
2032 cUnit->placeholderBB =
2033 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
2034 cUnit->func);
2035 }
2036 cUnit->idToBlockMap.Put(bb->id, llvmBB);
2037 }
2038 return false;
2039}
2040
2041
2042/*
2043 * Convert MIR to LLVM_IR
2044 * o For each ssa name, create LLVM named value. Type these
2045 * appropriately, and ignore high half of wide and double operands.
2046 * o For each MIR basic block, create an LLVM basic block.
2047 * o Iterate through the MIR a basic block at a time, setting arguments
2048 * to recovered ssa name.
2049 */
2050void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
2051{
2052 initIR(cUnit);
2053 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
2054
2055 // Create the function
2056 createFunction(cUnit);
2057
2058 // Create an LLVM basic block for each MIR block in dfs preorder
2059 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
2060 kPreOrderDFSTraversal, false /* isIterative */);
2061 /*
2062 * Create an llvm named value for each MIR SSA name. Note: we'll use
2063 * placeholders for all non-argument values (because we haven't seen
2064 * the definition yet).
2065 */
2066 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2067 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2068 arg_iter++; /* Skip path method */
2069 for (int i = 0; i < cUnit->numSSARegs; i++) {
2070 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07002071 RegLocation rlTemp = cUnit->regLocation[i];
2072 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07002073 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
2074 } else if ((i < cUnit->numRegs) ||
2075 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07002076 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
2077 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07002078 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
2079 val->setName(llvmSSAName(cUnit, i));
buzbee2cfc6392012-05-07 14:51:40 -07002080 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
buzbee2cfc6392012-05-07 14:51:40 -07002081 } else {
2082 // Recover previously-created argument values
2083 llvm::Value* argVal = arg_iter++;
2084 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
2085 }
2086 }
buzbee2cfc6392012-05-07 14:51:40 -07002087
2088 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
2089 kPreOrderDFSTraversal, false /* Iterative */);
2090
buzbee4be777b2012-07-12 14:38:18 -07002091 /*
2092 * In a few rare cases of verification failure, the verifier will
2093 * replace one or more Dalvik opcodes with the special
2094 * throw-verification-failure opcode. This can leave the SSA graph
2095 * in an invalid state, as definitions may be lost, while uses retained.
2096 * To work around this problem, we insert placeholder definitions for
2097 * all Dalvik SSA regs in the "placeholder" block. Here, after
2098 * bitcode conversion is complete, we examine those placeholder definitions
2099 * and delete any with no references (which normally is all of them).
2100 *
2101 * If any definitions remain, we link the placeholder block into the
2102 * CFG. Otherwise, it is deleted.
2103 */
2104 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
2105 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
2106 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2107 DCHECK(inst != NULL);
2108 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2109 DCHECK(val != NULL);
2110 if (val->getNumUses() == 0) {
2111 inst->eraseFromParent();
2112 }
2113 }
2114 setDexOffset(cUnit, 0);
2115 if (cUnit->placeholderBB->empty()) {
2116 cUnit->placeholderBB->eraseFromParent();
2117 } else {
2118 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2119 cUnit->irb->CreateBr(cUnit->entryTargetBB);
2120 cUnit->entryTargetBB = cUnit->placeholderBB;
2121 }
2122 cUnit->irb->SetInsertPoint(cUnit->entryBB);
2123 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07002124
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002125 if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
2126 if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
2127 LOG(INFO) << "Bitcode verification FAILED for "
2128 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
2129 << " of size " << cUnit->insnsSize;
2130 cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
2131 }
2132 }
buzbee2cfc6392012-05-07 14:51:40 -07002133
buzbeead8f15e2012-06-18 14:49:45 -07002134 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
2135 // Write bitcode to file
2136 std::string errmsg;
2137 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
2138 oatReplaceSpecialChars(fname);
buzbee6459e7c2012-10-02 14:42:41 -07002139 // TODO: make configurable change naming mechanism to avoid fname length issues.
buzbee4f1181f2012-06-22 13:52:12 -07002140 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002141
buzbee6459e7c2012-10-02 14:42:41 -07002142 if (fname.size() > 240) {
2143 LOG(INFO) << "Warning: bitcode filename too long. Truncated.";
2144 fname.resize(240);
2145 }
2146
buzbeead8f15e2012-06-18 14:49:45 -07002147 llvm::OwningPtr<llvm::tool_output_file> out_file(
2148 new llvm::tool_output_file(fname.c_str(), errmsg,
2149 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002150
buzbeead8f15e2012-06-18 14:49:45 -07002151 if (!errmsg.empty()) {
2152 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2153 }
2154
2155 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2156 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002157 }
buzbee2cfc6392012-05-07 14:51:40 -07002158}
2159
2160RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2161 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002162 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002163 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2164 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002165 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002166 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002167 // FIXME: need to be more robust, handle FP and be in a position to
2168 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002169 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2170 memset(&res, 0, sizeof(res));
2171 res.location = kLocPhysReg;
2172 res.lowReg = oatAllocTemp(cUnit);
2173 res.home = true;
2174 res.sRegLow = INVALID_SREG;
2175 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002176 llvm::Type* ty = val->getType();
2177 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2178 (ty == cUnit->irb->getDoubleTy()));
2179 if (res.wide) {
2180 res.highReg = oatAllocTemp(cUnit);
2181 }
buzbee4f1181f2012-06-22 13:52:12 -07002182 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002183 } else {
2184 DCHECK_EQ(valName[0], 'v');
2185 int baseSReg = INVALID_SREG;
2186 sscanf(valName.c_str(), "v%d_", &baseSReg);
2187 res = cUnit->regLocation[baseSReg];
2188 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002189 }
2190 } else {
2191 res = it->second;
2192 }
2193 return res;
2194}
2195
2196Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2197{
2198 Instruction::Code res = Instruction::NOP;
2199 if (isWide) {
2200 switch(op) {
2201 case kOpAdd: res = Instruction::ADD_LONG; break;
2202 case kOpSub: res = Instruction::SUB_LONG; break;
2203 case kOpMul: res = Instruction::MUL_LONG; break;
2204 case kOpDiv: res = Instruction::DIV_LONG; break;
2205 case kOpRem: res = Instruction::REM_LONG; break;
2206 case kOpAnd: res = Instruction::AND_LONG; break;
2207 case kOpOr: res = Instruction::OR_LONG; break;
2208 case kOpXor: res = Instruction::XOR_LONG; break;
2209 case kOpLsl: res = Instruction::SHL_LONG; break;
2210 case kOpLsr: res = Instruction::USHR_LONG; break;
2211 case kOpAsr: res = Instruction::SHR_LONG; break;
2212 default: LOG(FATAL) << "Unexpected OpKind " << op;
2213 }
2214 } else if (isConst){
2215 switch(op) {
2216 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2217 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2218 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2219 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2220 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2221 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2222 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2223 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2224 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2225 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2226 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2227 default: LOG(FATAL) << "Unexpected OpKind " << op;
2228 }
2229 } else {
2230 switch(op) {
2231 case kOpAdd: res = Instruction::ADD_INT; break;
2232 case kOpSub: res = Instruction::SUB_INT; break;
2233 case kOpMul: res = Instruction::MUL_INT; break;
2234 case kOpDiv: res = Instruction::DIV_INT; break;
2235 case kOpRem: res = Instruction::REM_INT; break;
2236 case kOpAnd: res = Instruction::AND_INT; break;
2237 case kOpOr: res = Instruction::OR_INT; break;
2238 case kOpXor: res = Instruction::XOR_INT; break;
2239 case kOpLsl: res = Instruction::SHL_INT; break;
2240 case kOpLsr: res = Instruction::USHR_INT; break;
2241 case kOpAsr: res = Instruction::SHR_INT; break;
2242 default: LOG(FATAL) << "Unexpected OpKind " << op;
2243 }
2244 }
2245 return res;
2246}
2247
buzbee4f1181f2012-06-22 13:52:12 -07002248Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2249{
2250 Instruction::Code res = Instruction::NOP;
2251 if (isWide) {
2252 switch(op) {
2253 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2254 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2255 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2256 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2257 case kOpRem: res = Instruction::REM_DOUBLE; break;
2258 default: LOG(FATAL) << "Unexpected OpKind " << op;
2259 }
2260 } else {
2261 switch(op) {
2262 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2263 case kOpSub: res = Instruction::SUB_FLOAT; break;
2264 case kOpMul: res = Instruction::MUL_FLOAT; break;
2265 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2266 case kOpRem: res = Instruction::REM_FLOAT; break;
2267 default: LOG(FATAL) << "Unexpected OpKind " << op;
2268 }
2269 }
2270 return res;
2271}
2272
2273void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2274{
2275 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002276 /*
2277 * Normally, we won't ever generate an FP operation with an immediate
2278 * operand (not supported in Dex instruction set). However, the IR builder
2279 * may insert them - in particular for createNegFP. Recognize this case
2280 * and deal with it.
2281 */
2282 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2283 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2284 DCHECK(op2C == NULL);
2285 if ((op1C != NULL) && (op == kOpSub)) {
2286 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2287 if (rlDest.wide) {
2288 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2289 } else {
2290 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2291 }
buzbee4f1181f2012-06-22 13:52:12 -07002292 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002293 DCHECK(op1C == NULL);
2294 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2295 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2296 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2297 if (rlDest.wide) {
2298 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2299 } else {
2300 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2301 }
buzbee4f1181f2012-06-22 13:52:12 -07002302 }
2303}
2304
buzbee101305f2012-06-28 18:00:56 -07002305void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2306 Instruction::Code opcode)
2307{
2308 RegLocation rlDest = getLoc(cUnit, inst);
2309 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2310 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2311}
2312
buzbee76592632012-06-29 15:18:35 -07002313void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2314{
2315 RegLocation rlDest = getLoc(cUnit, inst);
2316 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2317 Instruction::Code opcode;
2318 if (rlDest.wide) {
2319 if (rlSrc.wide) {
2320 opcode = Instruction::LONG_TO_DOUBLE;
2321 } else {
2322 opcode = Instruction::INT_TO_DOUBLE;
2323 }
2324 } else {
2325 if (rlSrc.wide) {
2326 opcode = Instruction::LONG_TO_FLOAT;
2327 } else {
2328 opcode = Instruction::INT_TO_FLOAT;
2329 }
2330 }
2331 genConversion(cUnit, opcode, rlDest, rlSrc);
2332}
2333
TDYa1274ec8ccd2012-08-11 07:04:57 -07002334void cvtFPToInt(CompilationUnit* cUnit, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002335{
TDYa1274ec8ccd2012-08-11 07:04:57 -07002336 RegLocation rlDest = getLoc(cUnit, call_inst);
2337 RegLocation rlSrc = getLoc(cUnit, call_inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002338 Instruction::Code opcode;
2339 if (rlDest.wide) {
2340 if (rlSrc.wide) {
2341 opcode = Instruction::DOUBLE_TO_LONG;
2342 } else {
2343 opcode = Instruction::FLOAT_TO_LONG;
2344 }
2345 } else {
2346 if (rlSrc.wide) {
2347 opcode = Instruction::DOUBLE_TO_INT;
2348 } else {
2349 opcode = Instruction::FLOAT_TO_INT;
2350 }
2351 }
2352 genConversion(cUnit, opcode, rlDest, rlSrc);
2353}
2354
2355void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2356{
2357 RegLocation rlDest = getLoc(cUnit, inst);
2358 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2359 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2360}
2361
2362void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2363{
2364 RegLocation rlDest = getLoc(cUnit, inst);
2365 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2366 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2367 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2368 storeValue(cUnit, rlDest, rlSrc);
2369}
2370
2371void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2372{
2373 RegLocation rlDest = getLoc(cUnit, inst);
2374 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2375 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2376}
2377
2378
buzbee101305f2012-06-28 18:00:56 -07002379void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2380{
2381 // TODO: evaluate src/tgt types and add general support for more than int to long
2382 RegLocation rlDest = getLoc(cUnit, inst);
2383 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2384 DCHECK(rlDest.wide);
2385 DCHECK(!rlSrc.wide);
2386 DCHECK(!rlDest.fp);
2387 DCHECK(!rlSrc.fp);
2388 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2389 if (rlSrc.location == kLocPhysReg) {
2390 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2391 } else {
2392 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2393 }
2394 if (isSigned) {
2395 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2396 } else {
2397 loadConstant(cUnit, rlResult.highReg, 0);
2398 }
2399 storeValueWide(cUnit, rlDest, rlResult);
2400}
2401
buzbee2cfc6392012-05-07 14:51:40 -07002402void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2403{
2404 RegLocation rlDest = getLoc(cUnit, inst);
2405 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002406 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002407 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2408 if ((op == kOpSub) && (lhsImm != NULL)) {
2409 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002410 if (rlSrc1.wide) {
2411 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2412 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2413 } else {
2414 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2415 lhsImm->getSExtValue());
2416 }
buzbee4f1181f2012-06-22 13:52:12 -07002417 return;
2418 }
2419 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002420 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2421 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002422 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2423 if (!rlDest.wide && (constRhs != NULL)) {
buzbee2cfc6392012-05-07 14:51:40 -07002424 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
buzbee9a2487f2012-07-26 14:01:13 -07002425 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002426 } else {
2427 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002428 RegLocation rlSrc2;
2429 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002430 // ir_builder converts NOT_LONG to xor src, -1. Restore
2431 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2432 DCHECK_EQ(-1L, constRhs->getSExtValue());
2433 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002434 rlSrc2 = rlSrc1;
2435 } else {
2436 rlSrc2 = getLoc(cUnit, rhs);
2437 }
buzbee2cfc6392012-05-07 14:51:40 -07002438 if (rlDest.wide) {
2439 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2440 } else {
2441 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2442 }
2443 }
2444}
2445
buzbee2a83e8f2012-07-13 16:42:30 -07002446void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2447 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002448{
buzbee2a83e8f2012-07-13 16:42:30 -07002449 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2450 RegLocation rlDest = getLoc(cUnit, callInst);
2451 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2452 llvm::Value* rhs = callInst->getArgOperand(1);
2453 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2454 DCHECK(!rlDest.wide);
2455 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002456 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002457 RegLocation rlShift = getLoc(cUnit, rhs);
2458 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2459 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2460 } else {
2461 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2462 }
buzbee101305f2012-06-28 18:00:56 -07002463 }
2464}
2465
buzbee2cfc6392012-05-07 14:51:40 -07002466void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2467{
2468 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2469 DCHECK(brInst != NULL);
2470 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2471 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2472 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2473}
2474
2475void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2476{
2477 // Nop - these have already been processed
2478}
2479
2480void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2481{
2482 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2483 llvm::Value* retVal = retInst->getReturnValue();
2484 if (retVal != NULL) {
2485 RegLocation rlSrc = getLoc(cUnit, retVal);
2486 if (rlSrc.wide) {
2487 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2488 } else {
2489 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2490 }
2491 }
2492 genExitSequence(cUnit);
2493}
2494
2495ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2496{
2497 ConditionCode res = kCondAl;
2498 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002499 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002500 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2501 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2502 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002503 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002504 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002505 default: LOG(FATAL) << "Unexpected llvm condition";
2506 }
2507 return res;
2508}
2509
2510void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2511{
2512 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2513 UNIMPLEMENTED(FATAL);
2514}
2515
2516void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2517 llvm::BranchInst* brInst)
2518{
2519 // Get targets
2520 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2521 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2522 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2523 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2524 // Get comparison operands
2525 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2526 ConditionCode cond = getCond(iCmpInst->getPredicate());
2527 llvm::Value* lhs = iCmpInst->getOperand(0);
2528 // Not expecting a constant as 1st operand
2529 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2530 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2531 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2532 llvm::Value* rhs = inst->getOperand(1);
buzbeeb046e162012-10-30 15:48:42 -07002533 if (cUnit->instructionSet == kMips) {
2534 // Compare and branch in one shot
2535 UNIMPLEMENTED(FATAL);
2536 }
buzbee2cfc6392012-05-07 14:51:40 -07002537 //Compare, then branch
2538 // TODO: handle fused CMP_LONG/IF_xxZ case
2539 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2540 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002541 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2542 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002543 } else {
2544 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2545 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2546 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2547 }
2548 opCondBranch(cUnit, cond, taken);
buzbee2cfc6392012-05-07 14:51:40 -07002549 // Fallthrough
2550 opUnconditionalBranch(cUnit, fallThrough);
2551}
2552
2553void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2554 llvm::Function* callee)
2555{
2556 UNIMPLEMENTED(FATAL);
2557}
2558
buzbee2cfc6392012-05-07 14:51:40 -07002559void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2560{
buzbee4f1181f2012-06-22 13:52:12 -07002561 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002562 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2563 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002564 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2565 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002566 if (rlSrc.wide) {
2567 storeValueWide(cUnit, rlDest, rlSrc);
2568 } else {
2569 storeValue(cUnit, rlDest, rlSrc);
2570 }
2571}
2572
2573// Note: Immediate arg is a ConstantInt regardless of result type
2574void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2575{
buzbee4f1181f2012-06-22 13:52:12 -07002576 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002577 llvm::ConstantInt* src =
2578 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2579 uint64_t immval = src->getZExtValue();
2580 RegLocation rlDest = getLoc(cUnit, callInst);
2581 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2582 if (rlDest.wide) {
2583 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2584 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2585 storeValueWide(cUnit, rlDest, rlResult);
2586 } else {
2587 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2588 storeValue(cUnit, rlDest, rlResult);
2589 }
2590}
2591
buzbee101305f2012-06-28 18:00:56 -07002592void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2593 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002594{
buzbee4f1181f2012-06-22 13:52:12 -07002595 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002596 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002597 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002598 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002599 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002600 if (isString) {
2601 genConstString(cUnit, index, rlDest);
2602 } else {
2603 genConstClass(cUnit, index, rlDest);
2604 }
2605}
2606
2607void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2608{
2609 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2610 llvm::ConstantInt* offsetVal =
2611 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2612 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2613 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002614}
2615
buzbee4f1181f2012-06-22 13:52:12 -07002616void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2617{
buzbee32412962012-06-26 16:27:56 -07002618 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002619 llvm::ConstantInt* typeIdxVal =
2620 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2621 uint32_t typeIdx = typeIdxVal->getZExtValue();
2622 RegLocation rlDest = getLoc(cUnit, callInst);
2623 genNewInstance(cUnit, typeIdx, rlDest);
2624}
2625
buzbee8fa0fda2012-06-27 15:44:52 -07002626void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2627{
2628 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2629 llvm::ConstantInt* typeIdxVal =
2630 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2631 uint32_t typeIdx = typeIdxVal->getZExtValue();
2632 llvm::Value* len = callInst->getArgOperand(1);
2633 RegLocation rlLen = getLoc(cUnit, len);
2634 RegLocation rlDest = getLoc(cUnit, callInst);
2635 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2636}
2637
2638void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2639{
2640 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2641 llvm::ConstantInt* typeIdxVal =
2642 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2643 uint32_t typeIdx = typeIdxVal->getZExtValue();
2644 llvm::Value* src = callInst->getArgOperand(1);
2645 RegLocation rlSrc = getLoc(cUnit, src);
2646 RegLocation rlDest = getLoc(cUnit, callInst);
2647 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2648}
2649
buzbee32412962012-06-26 16:27:56 -07002650void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2651{
2652 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2653 llvm::Value* src = callInst->getArgOperand(0);
2654 RegLocation rlSrc = getLoc(cUnit, src);
2655 genThrow(cUnit, rlSrc);
2656}
2657
buzbee8fa0fda2012-06-27 15:44:52 -07002658void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2659 llvm::CallInst* callInst)
2660{
2661 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2662 llvm::ConstantInt* optFlags =
2663 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2664 llvm::Value* src = callInst->getArgOperand(1);
2665 RegLocation rlSrc = getLoc(cUnit, src);
2666 if (isEnter) {
2667 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2668 } else {
2669 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2670 }
2671}
2672
buzbee76592632012-06-29 15:18:35 -07002673void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002674{
2675 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2676 llvm::ConstantInt* optFlags =
2677 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2678 llvm::Value* src = callInst->getArgOperand(1);
2679 RegLocation rlSrc = getLoc(cUnit, src);
2680 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2681 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2682 RegLocation rlDest = getLoc(cUnit, callInst);
2683 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2684 int lenOffset = Array::LengthOffset().Int32Value();
2685 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2686 storeValue(cUnit, rlDest, rlResult);
2687}
2688
buzbee32412962012-06-26 16:27:56 -07002689void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2690{
buzbee32412962012-06-26 16:27:56 -07002691 RegLocation rlDest = getLoc(cUnit, callInst);
Ian Rogers474b6da2012-09-25 00:20:38 -07002692 genMoveException(cUnit, rlDest);
buzbee32412962012-06-26 16:27:56 -07002693}
2694
buzbee4f1181f2012-06-22 13:52:12 -07002695void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2696 bool isObject)
2697{
buzbee32412962012-06-26 16:27:56 -07002698 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002699 llvm::ConstantInt* typeIdxVal =
2700 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2701 uint32_t typeIdx = typeIdxVal->getZExtValue();
2702 RegLocation rlDest = getLoc(cUnit, callInst);
2703 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2704}
2705
buzbee8fa0fda2012-06-27 15:44:52 -07002706void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2707 bool isObject)
2708{
2709 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2710 llvm::ConstantInt* typeIdxVal =
2711 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2712 uint32_t typeIdx = typeIdxVal->getZExtValue();
2713 llvm::Value* src = callInst->getArgOperand(1);
2714 RegLocation rlSrc = getLoc(cUnit, src);
2715 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2716}
2717
2718void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2719 int scale)
2720{
2721 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2722 llvm::ConstantInt* optFlags =
2723 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2724 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2725 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2726 RegLocation rlDest = getLoc(cUnit, callInst);
2727 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2728 rlDest, scale);
2729}
2730
2731void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002732 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002733{
2734 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2735 llvm::ConstantInt* optFlags =
2736 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2737 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2738 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2739 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002740 if (isObject) {
2741 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2742 rlSrc, scale);
2743 } else {
2744 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2745 rlSrc, scale);
2746 }
2747}
2748
2749void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2750{
2751 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2752}
2753
2754void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2755 OpSize size, int scale)
2756{
2757 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002758}
2759
buzbee101305f2012-06-28 18:00:56 -07002760void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2761 bool isWide, bool isObj)
2762{
2763 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2764 llvm::ConstantInt* optFlags =
2765 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2766 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2767 llvm::ConstantInt* fieldIdx =
2768 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2769 RegLocation rlDest = getLoc(cUnit, callInst);
2770 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2771 size, rlDest, rlObj, isWide, isObj);
2772}
2773
2774void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2775 bool isWide, bool isObj)
2776{
2777 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2778 llvm::ConstantInt* optFlags =
2779 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2780 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2781 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2782 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002783 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002784 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2785 size, rlSrc, rlObj, isWide, isObj);
2786}
2787
2788void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2789{
2790 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2791 llvm::ConstantInt* typeIdx =
2792 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2793 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2794 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2795}
2796
buzbee76592632012-06-29 15:18:35 -07002797void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2798 Instruction::Code opcode)
2799{
2800 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2801 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2802 RegLocation rlDest = getLoc(cUnit, callInst);
2803 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2804}
2805
2806void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2807{
2808 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2809 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2810 RegLocation rlDest = getLoc(cUnit, callInst);
2811 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2812}
2813
buzbeef58c12c2012-07-03 15:06:29 -07002814void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2815{
2816 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2817 DCHECK(swInst != NULL);
2818 llvm::Value* testVal = swInst->getCondition();
2819 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2820 DCHECK(tableOffsetNode != NULL);
2821 llvm::ConstantInt* tableOffsetValue =
2822 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2823 int32_t tableOffset = tableOffsetValue->getSExtValue();
2824 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeeeaf09bc2012-11-15 14:51:41 -08002825 const uint16_t* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2826 uint16_t tableMagic = *table;
buzbeea1da8a52012-07-09 14:00:21 -07002827 if (tableMagic == 0x100) {
2828 genPackedSwitch(cUnit, tableOffset, rlSrc);
2829 } else {
2830 DCHECK_EQ(tableMagic, 0x200);
2831 genSparseSwitch(cUnit, tableOffset, rlSrc);
2832 }
buzbeef58c12c2012-07-03 15:06:29 -07002833}
2834
buzbee6969d502012-06-15 16:40:31 -07002835void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002836 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002837{
2838 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2839 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002840 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002841 info->result.location = kLocInvalid;
2842 } else {
2843 info->result = getLoc(cUnit, callInst);
2844 }
2845 llvm::ConstantInt* invokeTypeVal =
2846 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2847 llvm::ConstantInt* methodIndexVal =
2848 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2849 llvm::ConstantInt* optFlagsVal =
2850 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2851 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2852 info->index = methodIndexVal->getZExtValue();
2853 info->optFlags = optFlagsVal->getZExtValue();
2854 info->offset = cUnit->currentDalvikOffset;
2855
buzbee6969d502012-06-15 16:40:31 -07002856 // Count the argument words, and then build argument array.
2857 info->numArgWords = 0;
2858 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2859 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2860 info->numArgWords += tLoc.wide ? 2 : 1;
2861 }
2862 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2863 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2864 // Now, fill in the location records, synthesizing high loc of wide vals
2865 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002866 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002867 if (info->args[next].wide) {
2868 next++;
2869 // TODO: Might make sense to mark this as an invalid loc
2870 info->args[next].origSReg = info->args[next-1].origSReg+1;
2871 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2872 }
2873 next++;
2874 }
buzbee4f4dfc72012-07-02 14:54:44 -07002875 // TODO - rework such that we no longer need isRange
2876 info->isRange = (info->numArgWords > 5);
2877
buzbee76592632012-06-29 15:18:35 -07002878 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002879 genFilledNewArray(cUnit, info);
2880 } else {
2881 genInvoke(cUnit, info);
2882 }
buzbee6969d502012-06-15 16:40:31 -07002883}
2884
buzbeead8f15e2012-06-18 14:49:45 -07002885/* Look up the RegLocation associated with a Value. Must already be defined */
2886RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2887{
2888 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2889 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2890 return it->second;
2891}
2892
buzbee2cfc6392012-05-07 14:51:40 -07002893bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2894{
buzbee0967a252012-09-14 10:43:54 -07002895 while (cUnit->llvmBlocks.find(bb) == cUnit->llvmBlocks.end()) {
2896 llvm::BasicBlock* nextBB = NULL;
2897 cUnit->llvmBlocks.insert(bb);
2898 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2899 // Define the starting label
2900 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2901 // Extract the type and starting offset from the block's name
buzbee951c0a12012-10-03 16:31:39 -07002902 char blockType = kInvalidBlock;
2903 if (isEntry) {
2904 blockType = kNormalBlock;
2905 blockLabel->operands[0] = 0;
2906 } else if (!bb->hasName()) {
2907 blockType = kNormalBlock;
2908 blockLabel->operands[0] = DexFile::kDexNoIndex;
buzbee0967a252012-09-14 10:43:54 -07002909 } else {
buzbee951c0a12012-10-03 16:31:39 -07002910 std::string blockName = bb->getName().str();
2911 int dummy;
2912 sscanf(blockName.c_str(), kLabelFormat, &blockType, &blockLabel->operands[0], &dummy);
2913 cUnit->currentDalvikOffset = blockLabel->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002914 }
buzbee951c0a12012-10-03 16:31:39 -07002915 DCHECK((blockType == kNormalBlock) || (blockType == kCatchBlock));
2916 cUnit->currentDalvikOffset = blockLabel->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002917 // Set the label kind
2918 blockLabel->opcode = kPseudoNormalBlockLabel;
2919 // Insert the label
2920 oatAppendLIR(cUnit, blockLabel);
buzbee2cfc6392012-05-07 14:51:40 -07002921
buzbee0967a252012-09-14 10:43:54 -07002922 LIR* headLIR = NULL;
buzbee8320f382012-09-11 16:29:42 -07002923
buzbee0967a252012-09-14 10:43:54 -07002924 if (blockType == kCatchBlock) {
Bill Buzbeea5b30242012-09-28 07:19:44 -07002925 headLIR = newLIR0(cUnit, kPseudoExportedPC);
buzbee0967a252012-09-14 10:43:54 -07002926 }
buzbee8320f382012-09-11 16:29:42 -07002927
buzbee0967a252012-09-14 10:43:54 -07002928 // Free temp registers and reset redundant store tracking */
2929 oatResetRegPool(cUnit);
2930 oatResetDefTracking(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002931
buzbee0967a252012-09-14 10:43:54 -07002932 //TODO: restore oat incoming liveness optimization
2933 oatClobberAllRegs(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002934
buzbee0967a252012-09-14 10:43:54 -07002935 if (isEntry) {
2936 RegLocation* argLocs = (RegLocation*)
2937 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2938 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2939 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2940 // Skip past Method*
2941 it++;
2942 for (unsigned i = 0; it != it_end; ++it) {
2943 llvm::Value* val = it;
2944 argLocs[i++] = valToLoc(cUnit, val);
2945 llvm::Type* ty = val->getType();
2946 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2947 argLocs[i] = argLocs[i-1];
2948 argLocs[i].lowReg = argLocs[i].highReg;
2949 argLocs[i].origSReg++;
2950 argLocs[i].sRegLow = INVALID_SREG;
2951 argLocs[i].highWord = true;
2952 i++;
2953 }
2954 }
2955 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
2956 }
2957
2958 // Visit all of the instructions in the block
2959 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2960 llvm::Instruction* inst = it;
2961 llvm::BasicBlock::iterator nextIt = ++it;
2962 // Extract the Dalvik offset from the instruction
2963 uint32_t opcode = inst->getOpcode();
2964 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2965 if (dexOffsetNode != NULL) {
2966 llvm::ConstantInt* dexOffsetValue =
2967 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2968 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2969 }
2970
2971 oatResetRegPool(cUnit);
2972 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2973 oatClobberAllRegs(cUnit);
2974 }
2975
2976 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2977 oatResetDefTracking(cUnit);
2978 }
2979
2980 #ifndef NDEBUG
2981 /* Reset temp tracking sanity check */
2982 cUnit->liveSReg = INVALID_SREG;
2983 #endif
2984
2985 // TODO: use llvm opcode name here instead of "boundary" if verbose
2986 LIR* boundaryLIR = markBoundary(cUnit, cUnit->currentDalvikOffset, "boundary");
2987
2988 /* Remember the first LIR for thisl block*/
2989 if (headLIR == NULL) {
2990 headLIR = boundaryLIR;
2991 headLIR->defMask = ENCODE_ALL;
2992 }
2993
2994 switch(opcode) {
2995
2996 case llvm::Instruction::ICmp: {
2997 llvm::Instruction* nextInst = nextIt;
2998 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2999 if (brInst != NULL /* and... */) {
3000 cvtICmpBr(cUnit, inst, brInst);
3001 ++it;
3002 } else {
3003 cvtICmp(cUnit, inst);
3004 }
3005 }
3006 break;
3007
3008 case llvm::Instruction::Call: {
3009 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
3010 llvm::Function* callee = callInst->getCalledFunction();
3011 greenland::IntrinsicHelper::IntrinsicId id =
3012 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3013 switch (id) {
3014 case greenland::IntrinsicHelper::AllocaShadowFrame:
3015 case greenland::IntrinsicHelper::SetShadowFrameEntry:
3016 case greenland::IntrinsicHelper::PopShadowFrame:
TDYa1278e950c12012-11-02 09:58:19 -07003017 case greenland::IntrinsicHelper::SetVReg:
buzbee0967a252012-09-14 10:43:54 -07003018 // Ignore shadow frame stuff for quick compiler
3019 break;
3020 case greenland::IntrinsicHelper::CopyInt:
3021 case greenland::IntrinsicHelper::CopyObj:
3022 case greenland::IntrinsicHelper::CopyFloat:
3023 case greenland::IntrinsicHelper::CopyLong:
3024 case greenland::IntrinsicHelper::CopyDouble:
3025 cvtCopy(cUnit, callInst);
3026 break;
3027 case greenland::IntrinsicHelper::ConstInt:
3028 case greenland::IntrinsicHelper::ConstObj:
3029 case greenland::IntrinsicHelper::ConstLong:
3030 case greenland::IntrinsicHelper::ConstFloat:
3031 case greenland::IntrinsicHelper::ConstDouble:
3032 cvtConst(cUnit, callInst);
3033 break;
3034 case greenland::IntrinsicHelper::DivInt:
3035 case greenland::IntrinsicHelper::DivLong:
3036 cvtBinOp(cUnit, kOpDiv, inst);
3037 break;
3038 case greenland::IntrinsicHelper::RemInt:
3039 case greenland::IntrinsicHelper::RemLong:
3040 cvtBinOp(cUnit, kOpRem, inst);
3041 break;
3042 case greenland::IntrinsicHelper::MethodInfo:
3043 // Already dealt with - just ignore it here.
3044 break;
3045 case greenland::IntrinsicHelper::CheckSuspend:
3046 genSuspendTest(cUnit, 0 /* optFlags already applied */);
3047 break;
3048 case greenland::IntrinsicHelper::HLInvokeObj:
3049 case greenland::IntrinsicHelper::HLInvokeFloat:
3050 case greenland::IntrinsicHelper::HLInvokeDouble:
3051 case greenland::IntrinsicHelper::HLInvokeLong:
3052 case greenland::IntrinsicHelper::HLInvokeInt:
3053 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
3054 break;
3055 case greenland::IntrinsicHelper::HLInvokeVoid:
3056 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
3057 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003058 case greenland::IntrinsicHelper::HLFilledNewArray:
buzbee0967a252012-09-14 10:43:54 -07003059 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
3060 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003061 case greenland::IntrinsicHelper::HLFillArrayData:
buzbee0967a252012-09-14 10:43:54 -07003062 cvtFillArrayData(cUnit, callInst);
3063 break;
3064 case greenland::IntrinsicHelper::ConstString:
3065 cvtConstObject(cUnit, callInst, true /* isString */);
3066 break;
3067 case greenland::IntrinsicHelper::ConstClass:
3068 cvtConstObject(cUnit, callInst, false /* isString */);
3069 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003070 case greenland::IntrinsicHelper::HLCheckCast:
buzbee0967a252012-09-14 10:43:54 -07003071 cvtCheckCast(cUnit, callInst);
3072 break;
3073 case greenland::IntrinsicHelper::NewInstance:
3074 cvtNewInstance(cUnit, callInst);
3075 break;
3076 case greenland::IntrinsicHelper::HLSgetObject:
3077 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
3078 break;
3079 case greenland::IntrinsicHelper::HLSget:
3080 case greenland::IntrinsicHelper::HLSgetFloat:
3081 case greenland::IntrinsicHelper::HLSgetBoolean:
3082 case greenland::IntrinsicHelper::HLSgetByte:
3083 case greenland::IntrinsicHelper::HLSgetChar:
3084 case greenland::IntrinsicHelper::HLSgetShort:
3085 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
3086 break;
3087 case greenland::IntrinsicHelper::HLSgetWide:
3088 case greenland::IntrinsicHelper::HLSgetDouble:
3089 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
3090 break;
3091 case greenland::IntrinsicHelper::HLSput:
3092 case greenland::IntrinsicHelper::HLSputFloat:
3093 case greenland::IntrinsicHelper::HLSputBoolean:
3094 case greenland::IntrinsicHelper::HLSputByte:
3095 case greenland::IntrinsicHelper::HLSputChar:
3096 case greenland::IntrinsicHelper::HLSputShort:
3097 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
3098 break;
3099 case greenland::IntrinsicHelper::HLSputWide:
3100 case greenland::IntrinsicHelper::HLSputDouble:
3101 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
3102 break;
3103 case greenland::IntrinsicHelper::HLSputObject:
3104 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
3105 break;
3106 case greenland::IntrinsicHelper::GetException:
3107 cvtMoveException(cUnit, callInst);
3108 break;
TDYa127f71bf5a2012-07-29 20:09:52 -07003109 case greenland::IntrinsicHelper::HLThrowException:
buzbee0967a252012-09-14 10:43:54 -07003110 cvtThrow(cUnit, callInst);
3111 break;
3112 case greenland::IntrinsicHelper::MonitorEnter:
3113 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
3114 break;
3115 case greenland::IntrinsicHelper::MonitorExit:
3116 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
3117 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003118 case greenland::IntrinsicHelper::OptArrayLength:
buzbee0967a252012-09-14 10:43:54 -07003119 cvtArrayLength(cUnit, callInst);
3120 break;
3121 case greenland::IntrinsicHelper::NewArray:
3122 cvtNewArray(cUnit, callInst);
3123 break;
3124 case greenland::IntrinsicHelper::InstanceOf:
3125 cvtInstanceOf(cUnit, callInst);
3126 break;
3127
3128 case greenland::IntrinsicHelper::HLArrayGet:
3129 case greenland::IntrinsicHelper::HLArrayGetObject:
3130 case greenland::IntrinsicHelper::HLArrayGetFloat:
3131 cvtAget(cUnit, callInst, kWord, 2);
3132 break;
3133 case greenland::IntrinsicHelper::HLArrayGetWide:
3134 case greenland::IntrinsicHelper::HLArrayGetDouble:
3135 cvtAget(cUnit, callInst, kLong, 3);
3136 break;
3137 case greenland::IntrinsicHelper::HLArrayGetBoolean:
3138 cvtAget(cUnit, callInst, kUnsignedByte, 0);
3139 break;
3140 case greenland::IntrinsicHelper::HLArrayGetByte:
3141 cvtAget(cUnit, callInst, kSignedByte, 0);
3142 break;
3143 case greenland::IntrinsicHelper::HLArrayGetChar:
3144 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
3145 break;
3146 case greenland::IntrinsicHelper::HLArrayGetShort:
3147 cvtAget(cUnit, callInst, kSignedHalf, 1);
3148 break;
3149
3150 case greenland::IntrinsicHelper::HLArrayPut:
3151 case greenland::IntrinsicHelper::HLArrayPutFloat:
3152 cvtAputPrimitive(cUnit, callInst, kWord, 2);
3153 break;
3154 case greenland::IntrinsicHelper::HLArrayPutObject:
3155 cvtAputObj(cUnit, callInst);
3156 break;
3157 case greenland::IntrinsicHelper::HLArrayPutWide:
3158 case greenland::IntrinsicHelper::HLArrayPutDouble:
3159 cvtAputPrimitive(cUnit, callInst, kLong, 3);
3160 break;
3161 case greenland::IntrinsicHelper::HLArrayPutBoolean:
3162 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
3163 break;
3164 case greenland::IntrinsicHelper::HLArrayPutByte:
3165 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
3166 break;
3167 case greenland::IntrinsicHelper::HLArrayPutChar:
3168 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
3169 break;
3170 case greenland::IntrinsicHelper::HLArrayPutShort:
3171 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
3172 break;
3173
3174 case greenland::IntrinsicHelper::HLIGet:
3175 case greenland::IntrinsicHelper::HLIGetFloat:
3176 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3177 break;
3178 case greenland::IntrinsicHelper::HLIGetObject:
3179 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3180 break;
3181 case greenland::IntrinsicHelper::HLIGetWide:
3182 case greenland::IntrinsicHelper::HLIGetDouble:
3183 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3184 break;
3185 case greenland::IntrinsicHelper::HLIGetBoolean:
3186 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3187 false /* obj */);
3188 break;
3189 case greenland::IntrinsicHelper::HLIGetByte:
3190 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3191 false /* obj */);
3192 break;
3193 case greenland::IntrinsicHelper::HLIGetChar:
3194 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3195 false /* obj */);
3196 break;
3197 case greenland::IntrinsicHelper::HLIGetShort:
3198 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3199 false /* obj */);
3200 break;
3201
3202 case greenland::IntrinsicHelper::HLIPut:
3203 case greenland::IntrinsicHelper::HLIPutFloat:
3204 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3205 break;
3206 case greenland::IntrinsicHelper::HLIPutObject:
3207 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3208 break;
3209 case greenland::IntrinsicHelper::HLIPutWide:
3210 case greenland::IntrinsicHelper::HLIPutDouble:
3211 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3212 break;
3213 case greenland::IntrinsicHelper::HLIPutBoolean:
3214 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3215 false /* obj */);
3216 break;
3217 case greenland::IntrinsicHelper::HLIPutByte:
3218 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3219 false /* obj */);
3220 break;
3221 case greenland::IntrinsicHelper::HLIPutChar:
3222 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3223 false /* obj */);
3224 break;
3225 case greenland::IntrinsicHelper::HLIPutShort:
3226 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3227 false /* obj */);
3228 break;
3229
3230 case greenland::IntrinsicHelper::IntToChar:
3231 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3232 break;
3233 case greenland::IntrinsicHelper::IntToShort:
3234 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3235 break;
3236 case greenland::IntrinsicHelper::IntToByte:
3237 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3238 break;
3239
TDYa1274ec8ccd2012-08-11 07:04:57 -07003240 case greenland::IntrinsicHelper::F2I:
3241 case greenland::IntrinsicHelper::D2I:
3242 case greenland::IntrinsicHelper::F2L:
3243 case greenland::IntrinsicHelper::D2L:
3244 cvtFPToInt(cUnit, callInst);
3245 break;
3246
buzbee0967a252012-09-14 10:43:54 -07003247 case greenland::IntrinsicHelper::CmplFloat:
3248 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3249 break;
3250 case greenland::IntrinsicHelper::CmpgFloat:
3251 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3252 break;
3253 case greenland::IntrinsicHelper::CmplDouble:
3254 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3255 break;
3256 case greenland::IntrinsicHelper::CmpgDouble:
3257 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3258 break;
3259
3260 case greenland::IntrinsicHelper::CmpLong:
3261 cvtLongCompare(cUnit, callInst);
3262 break;
3263
3264 case greenland::IntrinsicHelper::SHLLong:
3265 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
3266 break;
3267 case greenland::IntrinsicHelper::SHRLong:
3268 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3269 break;
3270 case greenland::IntrinsicHelper::USHRLong:
3271 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3272 break;
3273 case greenland::IntrinsicHelper::SHLInt:
3274 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3275 break;
3276 case greenland::IntrinsicHelper::SHRInt:
3277 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3278 break;
3279 case greenland::IntrinsicHelper::USHRInt:
3280 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3281 break;
3282
3283 case greenland::IntrinsicHelper::CatchTargets: {
3284 llvm::SwitchInst* swInst =
3285 llvm::dyn_cast<llvm::SwitchInst>(nextIt);
3286 DCHECK(swInst != NULL);
3287 /*
3288 * Discard the edges and the following conditional branch.
3289 * Do a direct branch to the default target (which is the
3290 * "work" portion of the pair.
3291 * TODO: awful code layout - rework
3292 */
3293 llvm::BasicBlock* targetBB = swInst->getDefaultDest();
3294 DCHECK(targetBB != NULL);
3295 opUnconditionalBranch(cUnit,
3296 cUnit->blockToLabelMap.Get(targetBB));
3297 ++it;
3298 // Set next bb to default target - improves code layout
3299 nextBB = targetBB;
3300 }
3301 break;
3302
3303 default:
3304 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3305 << cUnit->intrinsic_helper->GetName(id);
3306 }
3307 }
3308 break;
3309
3310 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3311 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3312 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3313 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3314 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3315 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3316 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3317 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3318 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
3319 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3320 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
3321 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3322 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3323 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3324 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3325 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
3326 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003327 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3328 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3329 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
3330
3331 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3332 break;
3333 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3334 break;
3335
3336 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3337
3338 case llvm::Instruction::Unreachable:
3339 break; // FIXME: can we really ignore these?
3340
3341 case llvm::Instruction::Shl:
3342 case llvm::Instruction::LShr:
3343 case llvm::Instruction::AShr:
3344 case llvm::Instruction::Invoke:
3345 case llvm::Instruction::FPToUI:
TDYa1274ec8ccd2012-08-11 07:04:57 -07003346 case llvm::Instruction::FPToSI:
buzbee0967a252012-09-14 10:43:54 -07003347 case llvm::Instruction::UIToFP:
3348 case llvm::Instruction::PtrToInt:
3349 case llvm::Instruction::IntToPtr:
3350 case llvm::Instruction::FCmp:
3351 case llvm::Instruction::URem:
3352 case llvm::Instruction::UDiv:
3353 case llvm::Instruction::Resume:
3354 case llvm::Instruction::Alloca:
3355 case llvm::Instruction::GetElementPtr:
3356 case llvm::Instruction::Fence:
3357 case llvm::Instruction::AtomicCmpXchg:
3358 case llvm::Instruction::AtomicRMW:
3359 case llvm::Instruction::BitCast:
3360 case llvm::Instruction::VAArg:
3361 case llvm::Instruction::Select:
3362 case llvm::Instruction::UserOp1:
3363 case llvm::Instruction::UserOp2:
3364 case llvm::Instruction::ExtractElement:
3365 case llvm::Instruction::InsertElement:
3366 case llvm::Instruction::ShuffleVector:
3367 case llvm::Instruction::ExtractValue:
3368 case llvm::Instruction::InsertValue:
3369 case llvm::Instruction::LandingPad:
3370 case llvm::Instruction::IndirectBr:
3371 case llvm::Instruction::Load:
3372 case llvm::Instruction::Store:
3373 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3374
3375 default:
3376 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3377 break;
buzbeead8f15e2012-06-18 14:49:45 -07003378 }
3379 }
buzbee2cfc6392012-05-07 14:51:40 -07003380
buzbee0967a252012-09-14 10:43:54 -07003381 if (headLIR != NULL) {
3382 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
buzbee2cfc6392012-05-07 14:51:40 -07003383 }
buzbee0967a252012-09-14 10:43:54 -07003384 if (nextBB != NULL) {
3385 bb = nextBB;
3386 nextBB = NULL;
buzbee6969d502012-06-15 16:40:31 -07003387 }
buzbee6969d502012-06-15 16:40:31 -07003388 }
buzbee2cfc6392012-05-07 14:51:40 -07003389 return false;
3390}
3391
3392/*
3393 * Convert LLVM_IR to MIR:
3394 * o Iterate through the LLVM_IR and construct a graph using
3395 * standard MIR building blocks.
3396 * o Perform a basic-block optimization pass to remove unnecessary
3397 * store/load sequences.
3398 * o Convert the LLVM Value operands into RegLocations where applicable.
3399 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3400 * o Perform register promotion
3401 * o Iterate through the graph a basic block at a time, generating
3402 * LIR.
3403 * o Assemble LIR as usual.
3404 * o Profit.
3405 */
3406void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3407{
buzbeead8f15e2012-06-18 14:49:45 -07003408 llvm::Function* func = cUnit->func;
3409 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003410 // Allocate a list for LIR basic block labels
3411 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07003412 (LIR*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3413 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003414 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003415 for (llvm::Function::iterator i = func->begin(),
3416 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003417 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3418 &labelList[nextLabel++]);
3419 }
buzbeead8f15e2012-06-18 14:49:45 -07003420
3421 /*
3422 * Keep honest - clear regLocations, Value => RegLocation,
3423 * promotion map and VmapTables.
3424 */
3425 cUnit->locMap.clear(); // Start fresh
3426 cUnit->regLocation = NULL;
3427 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3428 i++) {
3429 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3430 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3431 }
3432 cUnit->coreSpillMask = 0;
3433 cUnit->numCoreSpills = 0;
3434 cUnit->fpSpillMask = 0;
3435 cUnit->numFPSpills = 0;
3436 cUnit->coreVmapTable.clear();
3437 cUnit->fpVmapTable.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003438
3439 /*
3440 * At this point, we've lost all knowledge of register promotion.
3441 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003442 * exists - not required for correctness). Normally, this will
3443 * be the first instruction we encounter, so we won't have to iterate
3444 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003445 */
buzbeeca7a5e42012-08-20 11:12:18 -07003446 for (llvm::inst_iterator i = llvm::inst_begin(func),
3447 e = llvm::inst_end(func); i != e; ++i) {
3448 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(&*i);
3449 if (callInst != NULL) {
3450 llvm::Function* callee = callInst->getCalledFunction();
3451 greenland::IntrinsicHelper::IntrinsicId id =
3452 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3453 if (id == greenland::IntrinsicHelper::MethodInfo) {
3454 if (cUnit->printMe) {
3455 LOG(INFO) << "Found MethodInfo";
3456 }
3457 llvm::MDNode* regInfoNode = callInst->getMetadata("RegInfo");
3458 if (regInfoNode != NULL) {
3459 llvm::ConstantInt* numInsValue =
3460 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(0));
3461 llvm::ConstantInt* numRegsValue =
3462 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(1));
3463 llvm::ConstantInt* numOutsValue =
3464 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(2));
3465 llvm::ConstantInt* numCompilerTempsValue =
3466 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(3));
3467 llvm::ConstantInt* numSSARegsValue =
3468 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(4));
3469 if (cUnit->printMe) {
3470 LOG(INFO) << "RegInfo - Ins:" << numInsValue->getZExtValue()
3471 << ", Regs:" << numRegsValue->getZExtValue()
3472 << ", Outs:" << numOutsValue->getZExtValue()
3473 << ", CTemps:" << numCompilerTempsValue->getZExtValue()
3474 << ", SSARegs:" << numSSARegsValue->getZExtValue();
3475 }
3476 }
3477 llvm::MDNode* pmapInfoNode = callInst->getMetadata("PromotionMap");
3478 if (pmapInfoNode != NULL) {
3479 int elems = pmapInfoNode->getNumOperands();
3480 if (cUnit->printMe) {
3481 LOG(INFO) << "PMap size: " << elems;
3482 }
3483 for (int i = 0; i < elems; i++) {
3484 llvm::ConstantInt* rawMapData =
3485 static_cast<llvm::ConstantInt*>(pmapInfoNode->getOperand(i));
3486 uint32_t mapData = rawMapData->getZExtValue();
3487 PromotionMap* p = &cUnit->promotionMap[i];
3488 p->firstInPair = (mapData >> 24) & 0xff;
3489 p->fpReg = (mapData >> 16) & 0xff;
3490 p->coreReg = (mapData >> 8) & 0xff;
3491 p->fpLocation = static_cast<RegLocationType>((mapData >> 4) & 0xf);
3492 if (p->fpLocation == kLocPhysReg) {
3493 oatRecordFpPromotion(cUnit, p->fpReg, i);
3494 }
3495 p->coreLocation = static_cast<RegLocationType>(mapData & 0xf);
3496 if (p->coreLocation == kLocPhysReg) {
3497 oatRecordCorePromotion(cUnit, p->coreReg, i);
3498 }
3499 }
3500 if (cUnit->printMe) {
3501 oatDumpPromotionMap(cUnit);
3502 }
3503 }
3504 break;
3505 }
3506 }
3507 }
3508 oatAdjustSpillMask(cUnit);
3509 cUnit->frameSize = oatComputeFrameSize(cUnit);
buzbeead8f15e2012-06-18 14:49:45 -07003510
3511 // Create RegLocations for arguments
3512 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3513 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3514 for (; it != it_end; ++it) {
3515 llvm::Value* val = it;
3516 createLocFromValue(cUnit, val);
3517 }
3518 // Create RegLocations for all non-argument defintions
3519 for (llvm::inst_iterator i = llvm::inst_begin(func),
3520 e = llvm::inst_end(func); i != e; ++i) {
3521 llvm::Value* val = &*i;
3522 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3523 createLocFromValue(cUnit, val);
3524 }
3525 }
3526
buzbee2cfc6392012-05-07 14:51:40 -07003527 // Walk the blocks, generating code.
3528 for (llvm::Function::iterator i = cUnit->func->begin(),
3529 e = cUnit->func->end(); i != e; ++i) {
3530 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3531 }
3532
3533 handleSuspendLaunchpads(cUnit);
3534
3535 handleThrowLaunchpads(cUnit);
3536
3537 handleIntrinsicLaunchpads(cUnit);
3538
buzbee692be802012-08-29 15:52:59 -07003539 cUnit->func->eraseFromParent();
3540 cUnit->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003541}
3542
3543
3544} // namespace art