blob: be8f1f9d5c4a8f98889aae2def65591d91652d06 [file] [log] [blame]
buzbeee3acd072012-02-25 17:03:10 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "object_utils.h"
18
19namespace art {
20
21#define DISPLAY_MISSING_TARGETS (cUnit->enableDebug & \
22 (1 << kDebugDisplayMissingTargets))
23
buzbee31a4a6f2012-02-28 15:36:15 -080024const RegLocation badLoc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0,
25 INVALID_REG, INVALID_REG, INVALID_SREG};
buzbeee3acd072012-02-25 17:03:10 -080026
27/* Mark register usage state and return long retloc */
Ian Rogersf7d9ad32012-03-13 18:45:39 -070028RegLocation oatGetReturnWide(CompilationUnit* cUnit, bool isDouble)
buzbeee3acd072012-02-25 17:03:10 -080029{
Ian Rogersf7d9ad32012-03-13 18:45:39 -070030 RegLocation gpr_res = LOC_C_RETURN_WIDE;
31 RegLocation fpr_res = LOC_C_RETURN_WIDE_DOUBLE;
32 RegLocation res = isDouble ? fpr_res : gpr_res;
buzbee86a4bce2012-03-06 18:15:00 -080033 oatClobber(cUnit, res.lowReg);
34 oatClobber(cUnit, res.highReg);
buzbeee3acd072012-02-25 17:03:10 -080035 oatLockTemp(cUnit, res.lowReg);
36 oatLockTemp(cUnit, res.highReg);
37 oatMarkPair(cUnit, res.lowReg, res.highReg);
38 return res;
39}
40
Ian Rogersf7d9ad32012-03-13 18:45:39 -070041RegLocation oatGetReturn(CompilationUnit* cUnit, bool isFloat)
buzbeee3acd072012-02-25 17:03:10 -080042{
Ian Rogersf7d9ad32012-03-13 18:45:39 -070043 RegLocation gpr_res = LOC_C_RETURN;
44 RegLocation fpr_res = LOC_C_RETURN_FLOAT;
45 RegLocation res = isFloat ? fpr_res : gpr_res;
buzbee86a4bce2012-03-06 18:15:00 -080046 oatClobber(cUnit, res.lowReg);
Elliott Hughesb3cd1222012-03-09 16:00:38 -080047 if (cUnit->instructionSet == kMips) {
48 oatMarkInUse(cUnit, res.lowReg);
49 } else {
50 oatLockTemp(cUnit, res.lowReg);
51 }
buzbeee3acd072012-02-25 17:03:10 -080052 return res;
53}
54
buzbee31a4a6f2012-02-28 15:36:15 -080055void genInvoke(CompilationUnit* cUnit, MIR* mir, InvokeType type, bool isRange)
buzbeee3acd072012-02-25 17:03:10 -080056{
57 DecodedInstruction* dInsn = &mir->dalvikInsn;
58 int callState = 0;
buzbee31a4a6f2012-02-28 15:36:15 -080059 LIR* nullCk;
60 LIR** pNullCk = NULL;
buzbeee3acd072012-02-25 17:03:10 -080061 NextCallInsn nextCallInsn;
62 oatFlushAllRegs(cUnit); /* Everything to home location */
63 // Explicit register usage
64 oatLockCallTemps(cUnit);
65
Logan Chien4dd96f52012-02-29 01:26:58 +080066 OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
buzbee31a4a6f2012-02-28 15:36:15 -080067 *cUnit->dex_file, *cUnit->dex_cache,
68 cUnit->code_item, cUnit->method_idx,
69 cUnit->access_flags);
Logan Chien4dd96f52012-02-29 01:26:58 +080070
buzbeee3acd072012-02-25 17:03:10 -080071 uint32_t dexMethodIdx = dInsn->vB;
72 int vtableIdx;
73 bool skipThis;
74 bool fastPath =
Logan Chien4dd96f52012-02-29 01:26:58 +080075 cUnit->compiler->ComputeInvokeInfo(dexMethodIdx, &mUnit, type,
buzbeee3acd072012-02-25 17:03:10 -080076 vtableIdx)
77 && !SLOW_INVOKE_PATH;
78 if (type == kInterface) {
79 nextCallInsn = fastPath ? nextInterfaceCallInsn
80 : nextInterfaceCallInsnWithAccessCheck;
81 skipThis = false;
82 } else if (type == kDirect) {
83 if (fastPath) {
84 pNullCk = &nullCk;
85 }
86 nextCallInsn = fastPath ? nextSDCallInsn : nextDirectCallInsnSP;
87 skipThis = false;
88 } else if (type == kStatic) {
89 nextCallInsn = fastPath ? nextSDCallInsn : nextStaticCallInsnSP;
90 skipThis = false;
91 } else if (type == kSuper) {
92 nextCallInsn = fastPath ? nextSuperCallInsn : nextSuperCallInsnSP;
93 skipThis = fastPath;
94 } else {
95 DCHECK_EQ(type, kVirtual);
96 nextCallInsn = fastPath ? nextVCallInsn : nextVCallInsnSP;
97 skipThis = fastPath;
98 }
99 if (!isRange) {
100 callState = genDalvikArgsNoRange(cUnit, mir, dInsn, callState, pNullCk,
101 nextCallInsn, dexMethodIdx,
102 vtableIdx, skipThis);
103 } else {
104 callState = genDalvikArgsRange(cUnit, mir, dInsn, callState, pNullCk,
105 nextCallInsn, dexMethodIdx, vtableIdx,
106 skipThis);
107 }
108 // Finish up any of the call sequence not interleaved in arg loading
109 while (callState >= 0) {
110 callState = nextCallInsn(cUnit, mir, callState, dexMethodIdx,
111 vtableIdx);
112 }
113 if (DISPLAY_MISSING_TARGETS) {
114 genShowTarget(cUnit);
115 }
Ian Rogers6cbb2bd2012-03-16 13:45:30 -0700116#if !defined(TARGET_X86)
buzbee0398c422012-03-02 15:22:47 -0800117 opReg(cUnit, kOpBlx, rINVOKE_TGT);
Ian Rogers6cbb2bd2012-03-16 13:45:30 -0700118#else
119 if (fastPath) {
120 opMem(cUnit, kOpBlx, rARG0, Method::GetCodeOffset().Int32Value());
121 } else {
122 UNIMPLEMENTED(FATAL) << "compute trampoline";
123 opThreadMem(cUnit, kOpBlx, 0);
124 }
buzbeea7678db2012-03-05 15:35:46 -0800125#endif
Ian Rogers6cbb2bd2012-03-16 13:45:30 -0700126
127 oatClobberCalleeSave(cUnit);
buzbeee3acd072012-02-25 17:03:10 -0800128}
129
130/*
131 * Target-independent code generation. Use only high-level
132 * load/store utilities here, or target-dependent genXX() handlers
133 * when necessary.
134 */
buzbee31a4a6f2012-02-28 15:36:15 -0800135bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
136 BasicBlock* bb, LIR* labelList)
buzbeee3acd072012-02-25 17:03:10 -0800137{
138 bool res = false; // Assume success
139 RegLocation rlSrc[3];
140 RegLocation rlDest = badLoc;
141 RegLocation rlResult = badLoc;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800142 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbeee3acd072012-02-25 17:03:10 -0800143
144 /* Prep Src and Dest locations */
145 int nextSreg = 0;
146 int nextLoc = 0;
147 int attrs = oatDataFlowAttributes[opcode];
148 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
149 if (attrs & DF_UA) {
150 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
151 nextSreg++;
152 } else if (attrs & DF_UA_WIDE) {
153 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
154 nextSreg + 1);
155 nextSreg+= 2;
156 }
157 if (attrs & DF_UB) {
158 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
159 nextSreg++;
160 } else if (attrs & DF_UB_WIDE) {
161 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
162 nextSreg + 1);
163 nextSreg+= 2;
164 }
165 if (attrs & DF_UC) {
166 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
167 } else if (attrs & DF_UC_WIDE) {
168 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
169 nextSreg + 1);
170 }
171 if (attrs & DF_DA) {
172 rlDest = oatGetDest(cUnit, mir, 0);
173 } else if (attrs & DF_DA_WIDE) {
174 rlDest = oatGetDestWide(cUnit, mir, 0, 1);
175 }
176
177 switch(opcode) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800178 case Instruction::NOP:
buzbeee3acd072012-02-25 17:03:10 -0800179 break;
180
Elliott Hughesadb8c672012-03-06 16:49:32 -0800181 case Instruction::MOVE_EXCEPTION:
buzbeea7678db2012-03-05 15:35:46 -0800182#if defined(TARGET_X86)
Elliott Hughesadb8c672012-03-06 16:49:32 -0800183 UNIMPLEMENTED(WARNING) << "Instruction::MOVE_EXCEPTION";
buzbeea7678db2012-03-05 15:35:46 -0800184#else
buzbeee3acd072012-02-25 17:03:10 -0800185 int exOffset;
186 int resetReg;
187 exOffset = Thread::ExceptionOffset().Int32Value();
188 resetReg = oatAllocTemp(cUnit);
189 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
190 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
191 loadConstant(cUnit, resetReg, 0);
192 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
193 storeValue(cUnit, rlDest, rlResult);
buzbeea7678db2012-03-05 15:35:46 -0800194#endif
buzbeee3acd072012-02-25 17:03:10 -0800195 break;
196
Elliott Hughesadb8c672012-03-06 16:49:32 -0800197 case Instruction::RETURN_VOID:
buzbee86a4bce2012-03-06 18:15:00 -0800198 if (!cUnit->attrs & METHOD_IS_LEAF) {
199 genSuspendTest(cUnit, mir);
200 }
buzbeee3acd072012-02-25 17:03:10 -0800201 break;
202
Elliott Hughesadb8c672012-03-06 16:49:32 -0800203 case Instruction::RETURN:
204 case Instruction::RETURN_OBJECT:
buzbee86a4bce2012-03-06 18:15:00 -0800205 if (!cUnit->attrs & METHOD_IS_LEAF) {
206 genSuspendTest(cUnit, mir);
207 }
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700208 storeValue(cUnit, oatGetReturn(cUnit, cUnit->shorty[0] == 'F'),
209 rlSrc[0]);
buzbeee3acd072012-02-25 17:03:10 -0800210 break;
211
Elliott Hughesadb8c672012-03-06 16:49:32 -0800212 case Instruction::RETURN_WIDE:
buzbee86a4bce2012-03-06 18:15:00 -0800213 if (!cUnit->attrs & METHOD_IS_LEAF) {
214 genSuspendTest(cUnit, mir);
215 }
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700216 storeValueWide(cUnit, oatGetReturnWide(cUnit,
217 cUnit->shorty[0] == 'D'), rlSrc[0]);
buzbeee3acd072012-02-25 17:03:10 -0800218 break;
219
Elliott Hughesadb8c672012-03-06 16:49:32 -0800220 case Instruction::MOVE_RESULT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800221 if (mir->optimizationFlags & MIR_INLINED)
222 break; // Nop - combined w/ previous invoke
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700223 storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit, rlDest.fp));
buzbeee3acd072012-02-25 17:03:10 -0800224 break;
225
Elliott Hughesadb8c672012-03-06 16:49:32 -0800226 case Instruction::MOVE_RESULT:
227 case Instruction::MOVE_RESULT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800228 if (mir->optimizationFlags & MIR_INLINED)
229 break; // Nop - combined w/ previous invoke
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700230 storeValue(cUnit, rlDest, oatGetReturn(cUnit, rlDest.fp));
buzbeee3acd072012-02-25 17:03:10 -0800231 break;
232
Elliott Hughesadb8c672012-03-06 16:49:32 -0800233 case Instruction::MOVE:
234 case Instruction::MOVE_OBJECT:
235 case Instruction::MOVE_16:
236 case Instruction::MOVE_OBJECT_16:
237 case Instruction::MOVE_FROM16:
238 case Instruction::MOVE_OBJECT_FROM16:
buzbeee3acd072012-02-25 17:03:10 -0800239 storeValue(cUnit, rlDest, rlSrc[0]);
240 break;
241
Elliott Hughesadb8c672012-03-06 16:49:32 -0800242 case Instruction::MOVE_WIDE:
243 case Instruction::MOVE_WIDE_16:
244 case Instruction::MOVE_WIDE_FROM16:
buzbeee3acd072012-02-25 17:03:10 -0800245 storeValueWide(cUnit, rlDest, rlSrc[0]);
246 break;
247
Elliott Hughesadb8c672012-03-06 16:49:32 -0800248 case Instruction::CONST:
249 case Instruction::CONST_4:
250 case Instruction::CONST_16:
buzbeee3acd072012-02-25 17:03:10 -0800251 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
252 loadConstantNoClobber(cUnit, rlResult.lowReg, mir->dalvikInsn.vB);
253 storeValue(cUnit, rlDest, rlResult);
254 break;
255
Elliott Hughesadb8c672012-03-06 16:49:32 -0800256 case Instruction::CONST_HIGH16:
buzbeee3acd072012-02-25 17:03:10 -0800257 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
258 loadConstantNoClobber(cUnit, rlResult.lowReg,
259 mir->dalvikInsn.vB << 16);
260 storeValue(cUnit, rlDest, rlResult);
261 break;
262
Elliott Hughesadb8c672012-03-06 16:49:32 -0800263 case Instruction::CONST_WIDE_16:
264 case Instruction::CONST_WIDE_32:
buzbeee3acd072012-02-25 17:03:10 -0800265 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
266 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
267 mir->dalvikInsn.vB,
268 (mir->dalvikInsn.vB & 0x80000000) ? -1 : 0);
269 storeValueWide(cUnit, rlDest, rlResult);
270 break;
271
Elliott Hughesadb8c672012-03-06 16:49:32 -0800272 case Instruction::CONST_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800273 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
274 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
275 mir->dalvikInsn.vB_wide & 0xffffffff,
276 (mir->dalvikInsn.vB_wide >> 32) & 0xffffffff);
277 storeValueWide(cUnit, rlDest, rlResult);
278 break;
279
Elliott Hughesadb8c672012-03-06 16:49:32 -0800280 case Instruction::CONST_WIDE_HIGH16:
buzbeee3acd072012-02-25 17:03:10 -0800281 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
282 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
283 0, mir->dalvikInsn.vB << 16);
284 storeValueWide(cUnit, rlDest, rlResult);
285 break;
286
Elliott Hughesadb8c672012-03-06 16:49:32 -0800287 case Instruction::MONITOR_ENTER:
buzbeee3acd072012-02-25 17:03:10 -0800288 genMonitorEnter(cUnit, mir, rlSrc[0]);
289 break;
290
Elliott Hughesadb8c672012-03-06 16:49:32 -0800291 case Instruction::MONITOR_EXIT:
buzbeee3acd072012-02-25 17:03:10 -0800292 genMonitorExit(cUnit, mir, rlSrc[0]);
293 break;
294
Elliott Hughesadb8c672012-03-06 16:49:32 -0800295 case Instruction::CHECK_CAST:
buzbeee3acd072012-02-25 17:03:10 -0800296 genCheckCast(cUnit, mir, rlSrc[0]);
297 break;
298
Elliott Hughesadb8c672012-03-06 16:49:32 -0800299 case Instruction::INSTANCE_OF:
buzbeee3acd072012-02-25 17:03:10 -0800300 genInstanceof(cUnit, mir, rlDest, rlSrc[0]);
301 break;
302
Elliott Hughesadb8c672012-03-06 16:49:32 -0800303 case Instruction::NEW_INSTANCE:
buzbeee3acd072012-02-25 17:03:10 -0800304 genNewInstance(cUnit, mir, rlDest);
305 break;
306
Elliott Hughesadb8c672012-03-06 16:49:32 -0800307 case Instruction::THROW:
buzbeee3acd072012-02-25 17:03:10 -0800308 genThrow(cUnit, mir, rlSrc[0]);
309 break;
310
Elliott Hughesadb8c672012-03-06 16:49:32 -0800311 case Instruction::THROW_VERIFICATION_ERROR:
buzbeee3acd072012-02-25 17:03:10 -0800312 genThrowVerificationError(cUnit, mir);
313 break;
314
Elliott Hughesadb8c672012-03-06 16:49:32 -0800315 case Instruction::ARRAY_LENGTH:
buzbeee3acd072012-02-25 17:03:10 -0800316 int lenOffset;
317 lenOffset = Array::LengthOffset().Int32Value();
318 rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
319 genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, mir);
320 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
321 loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset,
322 rlResult.lowReg);
323 storeValue(cUnit, rlDest, rlResult);
324 break;
325
Elliott Hughesadb8c672012-03-06 16:49:32 -0800326 case Instruction::CONST_STRING:
327 case Instruction::CONST_STRING_JUMBO:
buzbeee3acd072012-02-25 17:03:10 -0800328 genConstString(cUnit, mir, rlDest, rlSrc[0]);
329 break;
330
Elliott Hughesadb8c672012-03-06 16:49:32 -0800331 case Instruction::CONST_CLASS:
buzbeee3acd072012-02-25 17:03:10 -0800332 genConstClass(cUnit, mir, rlDest, rlSrc[0]);
333 break;
334
Elliott Hughesadb8c672012-03-06 16:49:32 -0800335 case Instruction::FILL_ARRAY_DATA:
buzbeee3acd072012-02-25 17:03:10 -0800336 genFillArrayData(cUnit, mir, rlSrc[0]);
337 break;
338
Elliott Hughesadb8c672012-03-06 16:49:32 -0800339 case Instruction::FILLED_NEW_ARRAY:
buzbeee3acd072012-02-25 17:03:10 -0800340 genFilledNewArray(cUnit, mir, false /* not range */);
341 break;
342
Elliott Hughesadb8c672012-03-06 16:49:32 -0800343 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800344 genFilledNewArray(cUnit, mir, true /* range */);
345 break;
346
Elliott Hughesadb8c672012-03-06 16:49:32 -0800347 case Instruction::NEW_ARRAY:
buzbeee3acd072012-02-25 17:03:10 -0800348 genNewArray(cUnit, mir, rlDest, rlSrc[0]);
349 break;
350
Elliott Hughesadb8c672012-03-06 16:49:32 -0800351 case Instruction::GOTO:
352 case Instruction::GOTO_16:
353 case Instruction::GOTO_32:
buzbeee3acd072012-02-25 17:03:10 -0800354 if (bb->taken->startOffset <= mir->offset) {
355 genSuspendTest(cUnit, mir);
356 }
buzbee82488f52012-03-02 08:20:26 -0800357 opUnconditionalBranch(cUnit, &labelList[bb->taken->id]);
buzbeee3acd072012-02-25 17:03:10 -0800358 break;
359
Elliott Hughesadb8c672012-03-06 16:49:32 -0800360 case Instruction::PACKED_SWITCH:
buzbeee3acd072012-02-25 17:03:10 -0800361 genPackedSwitch(cUnit, mir, rlSrc[0]);
362 break;
363
Elliott Hughesadb8c672012-03-06 16:49:32 -0800364 case Instruction::SPARSE_SWITCH:
buzbeee3acd072012-02-25 17:03:10 -0800365 genSparseSwitch(cUnit, mir, rlSrc[0]);
366 break;
367
Elliott Hughesadb8c672012-03-06 16:49:32 -0800368 case Instruction::CMPL_FLOAT:
369 case Instruction::CMPG_FLOAT:
370 case Instruction::CMPL_DOUBLE:
371 case Instruction::CMPG_DOUBLE:
buzbeee3acd072012-02-25 17:03:10 -0800372 res = genCmpFP(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
373 break;
374
Elliott Hughesadb8c672012-03-06 16:49:32 -0800375 case Instruction::CMP_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800376 genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
377 break;
378
Elliott Hughesadb8c672012-03-06 16:49:32 -0800379 case Instruction::IF_EQ:
380 case Instruction::IF_NE:
381 case Instruction::IF_LT:
382 case Instruction::IF_GE:
383 case Instruction::IF_GT:
384 case Instruction::IF_LE: {
buzbeee3acd072012-02-25 17:03:10 -0800385 bool backwardBranch;
386 backwardBranch = (bb->taken->startOffset <= mir->offset);
387 if (backwardBranch) {
388 genSuspendTest(cUnit, mir);
389 }
390 genCompareAndBranch(cUnit, bb, mir, rlSrc[0], rlSrc[1], labelList);
391 break;
392 }
393
Elliott Hughesadb8c672012-03-06 16:49:32 -0800394 case Instruction::IF_EQZ:
395 case Instruction::IF_NEZ:
396 case Instruction::IF_LTZ:
397 case Instruction::IF_GEZ:
398 case Instruction::IF_GTZ:
399 case Instruction::IF_LEZ: {
buzbeee3acd072012-02-25 17:03:10 -0800400 bool backwardBranch;
401 backwardBranch = (bb->taken->startOffset <= mir->offset);
402 if (backwardBranch) {
403 genSuspendTest(cUnit, mir);
404 }
405 genCompareZeroAndBranch(cUnit, bb, mir, rlSrc[0], labelList);
406 break;
407 }
408
Elliott Hughesadb8c672012-03-06 16:49:32 -0800409 case Instruction::AGET_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800410 genArrayGet(cUnit, mir, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
411 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800412 case Instruction::AGET:
413 case Instruction::AGET_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800414 genArrayGet(cUnit, mir, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
415 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800416 case Instruction::AGET_BOOLEAN:
buzbeee3acd072012-02-25 17:03:10 -0800417 genArrayGet(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1],
418 rlDest, 0);
419 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800420 case Instruction::AGET_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800421 genArrayGet(cUnit, mir, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
422 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800423 case Instruction::AGET_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800424 genArrayGet(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1],
425 rlDest, 1);
426 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800427 case Instruction::AGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800428 genArrayGet(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
429 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800430 case Instruction::APUT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800431 genArrayPut(cUnit, mir, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
432 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800433 case Instruction::APUT:
buzbeee3acd072012-02-25 17:03:10 -0800434 genArrayPut(cUnit, mir, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
435 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800436 case Instruction::APUT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800437 genArrayObjPut(cUnit, mir, rlSrc[1], rlSrc[2], rlSrc[0], 2);
438 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800439 case Instruction::APUT_SHORT:
440 case Instruction::APUT_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800441 genArrayPut(cUnit, mir, kUnsignedHalf, rlSrc[1], rlSrc[2],
442 rlSrc[0], 1);
443 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800444 case Instruction::APUT_BYTE:
445 case Instruction::APUT_BOOLEAN:
buzbeee3acd072012-02-25 17:03:10 -0800446 genArrayPut(cUnit, mir, kUnsignedByte, rlSrc[1], rlSrc[2],
447 rlSrc[0], 0);
448 break;
449
Elliott Hughesadb8c672012-03-06 16:49:32 -0800450 case Instruction::IGET_OBJECT:
451 //case Instruction::IGET_OBJECT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800452 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, true);
453 break;
454
Elliott Hughesadb8c672012-03-06 16:49:32 -0800455 case Instruction::IGET_WIDE:
456 //case Instruction::IGET_WIDE_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800457 genIGet(cUnit, mir, kLong, rlDest, rlSrc[0], true, false);
458 break;
459
Elliott Hughesadb8c672012-03-06 16:49:32 -0800460 case Instruction::IGET:
461 //case Instruction::IGET_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800462 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, false);
463 break;
464
Elliott Hughesadb8c672012-03-06 16:49:32 -0800465 case Instruction::IGET_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800466 genIGet(cUnit, mir, kUnsignedHalf, rlDest, rlSrc[0], false, false);
467 break;
468
Elliott Hughesadb8c672012-03-06 16:49:32 -0800469 case Instruction::IGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800470 genIGet(cUnit, mir, kSignedHalf, rlDest, rlSrc[0], false, false);
471 break;
472
Elliott Hughesadb8c672012-03-06 16:49:32 -0800473 case Instruction::IGET_BOOLEAN:
474 case Instruction::IGET_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800475 genIGet(cUnit, mir, kUnsignedByte, rlDest, rlSrc[0], false, false);
476 break;
477
Elliott Hughesadb8c672012-03-06 16:49:32 -0800478 case Instruction::IPUT_WIDE:
479 //case Instruction::IPUT_WIDE_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800480 genIPut(cUnit, mir, kLong, rlSrc[0], rlSrc[1], true, false);
481 break;
482
Elliott Hughesadb8c672012-03-06 16:49:32 -0800483 case Instruction::IPUT_OBJECT:
484 //case Instruction::IPUT_OBJECT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800485 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, true);
486 break;
487
Elliott Hughesadb8c672012-03-06 16:49:32 -0800488 case Instruction::IPUT:
489 //case Instruction::IPUT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800490 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, false);
491 break;
492
Elliott Hughesadb8c672012-03-06 16:49:32 -0800493 case Instruction::IPUT_BOOLEAN:
494 case Instruction::IPUT_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800495 genIPut(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
496 break;
497
Elliott Hughesadb8c672012-03-06 16:49:32 -0800498 case Instruction::IPUT_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800499 genIPut(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
500 break;
501
Elliott Hughesadb8c672012-03-06 16:49:32 -0800502 case Instruction::IPUT_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800503 genIPut(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
504 break;
505
Elliott Hughesadb8c672012-03-06 16:49:32 -0800506 case Instruction::SGET_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800507 genSget(cUnit, mir, rlDest, false, true);
508 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800509 case Instruction::SGET:
510 case Instruction::SGET_BOOLEAN:
511 case Instruction::SGET_BYTE:
512 case Instruction::SGET_CHAR:
513 case Instruction::SGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800514 genSget(cUnit, mir, rlDest, false, false);
515 break;
516
Elliott Hughesadb8c672012-03-06 16:49:32 -0800517 case Instruction::SGET_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800518 genSget(cUnit, mir, rlDest, true, false);
519 break;
520
Elliott Hughesadb8c672012-03-06 16:49:32 -0800521 case Instruction::SPUT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800522 genSput(cUnit, mir, rlSrc[0], false, true);
523 break;
524
Elliott Hughesadb8c672012-03-06 16:49:32 -0800525 case Instruction::SPUT:
526 case Instruction::SPUT_BOOLEAN:
527 case Instruction::SPUT_BYTE:
528 case Instruction::SPUT_CHAR:
529 case Instruction::SPUT_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800530 genSput(cUnit, mir, rlSrc[0], false, false);
531 break;
532
Elliott Hughesadb8c672012-03-06 16:49:32 -0800533 case Instruction::SPUT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800534 genSput(cUnit, mir, rlSrc[0], true, false);
535 break;
536
Elliott Hughesadb8c672012-03-06 16:49:32 -0800537 case Instruction::INVOKE_STATIC_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800538 genInvoke(cUnit, mir, kStatic, true /*range*/);
539 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800540 case Instruction::INVOKE_STATIC:
buzbeee3acd072012-02-25 17:03:10 -0800541 genInvoke(cUnit, mir, kStatic, false /*range*/);
542 break;
543
Elliott Hughesadb8c672012-03-06 16:49:32 -0800544 case Instruction::INVOKE_DIRECT:
buzbeee3acd072012-02-25 17:03:10 -0800545 genInvoke(cUnit, mir, kDirect, false /*range*/);
546 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800547 case Instruction::INVOKE_DIRECT_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800548 genInvoke(cUnit, mir, kDirect, true /*range*/);
549 break;
550
Elliott Hughesadb8c672012-03-06 16:49:32 -0800551 case Instruction::INVOKE_VIRTUAL:
buzbeee3acd072012-02-25 17:03:10 -0800552 genInvoke(cUnit, mir, kVirtual, false /*range*/);
553 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800554 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800555 genInvoke(cUnit, mir, kVirtual, true /*range*/);
556 break;
557
Elliott Hughesadb8c672012-03-06 16:49:32 -0800558 case Instruction::INVOKE_SUPER:
buzbeee3acd072012-02-25 17:03:10 -0800559 genInvoke(cUnit, mir, kSuper, false /*range*/);
560 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800561 case Instruction::INVOKE_SUPER_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800562 genInvoke(cUnit, mir, kSuper, true /*range*/);
563 break;
564
Elliott Hughesadb8c672012-03-06 16:49:32 -0800565 case Instruction::INVOKE_INTERFACE:
buzbeee3acd072012-02-25 17:03:10 -0800566 genInvoke(cUnit, mir, kInterface, false /*range*/);
567 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800568 case Instruction::INVOKE_INTERFACE_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800569 genInvoke(cUnit, mir, kInterface, true /*range*/);
570 break;
571
Elliott Hughesadb8c672012-03-06 16:49:32 -0800572 case Instruction::NEG_INT:
573 case Instruction::NOT_INT:
buzbeee3acd072012-02-25 17:03:10 -0800574 res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
575 break;
576
Elliott Hughesadb8c672012-03-06 16:49:32 -0800577 case Instruction::NEG_LONG:
578 case Instruction::NOT_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800579 res = genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
580 break;
581
Elliott Hughesadb8c672012-03-06 16:49:32 -0800582 case Instruction::NEG_FLOAT:
buzbeee3acd072012-02-25 17:03:10 -0800583 res = genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
584 break;
585
Elliott Hughesadb8c672012-03-06 16:49:32 -0800586 case Instruction::NEG_DOUBLE:
buzbeee3acd072012-02-25 17:03:10 -0800587 res = genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
588 break;
589
Elliott Hughesadb8c672012-03-06 16:49:32 -0800590 case Instruction::INT_TO_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800591 genIntToLong(cUnit, mir, rlDest, rlSrc[0]);
592 break;
593
Elliott Hughesadb8c672012-03-06 16:49:32 -0800594 case Instruction::LONG_TO_INT:
buzbeee3acd072012-02-25 17:03:10 -0800595 rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
596 rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
597 storeValue(cUnit, rlDest, rlSrc[0]);
598 break;
599
Elliott Hughesadb8c672012-03-06 16:49:32 -0800600 case Instruction::INT_TO_BYTE:
601 case Instruction::INT_TO_SHORT:
602 case Instruction::INT_TO_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800603 genIntNarrowing(cUnit, mir, rlDest, rlSrc[0]);
604 break;
605
Elliott Hughesadb8c672012-03-06 16:49:32 -0800606 case Instruction::INT_TO_FLOAT:
607 case Instruction::INT_TO_DOUBLE:
608 case Instruction::LONG_TO_FLOAT:
609 case Instruction::LONG_TO_DOUBLE:
610 case Instruction::FLOAT_TO_INT:
611 case Instruction::FLOAT_TO_LONG:
612 case Instruction::FLOAT_TO_DOUBLE:
613 case Instruction::DOUBLE_TO_INT:
614 case Instruction::DOUBLE_TO_LONG:
615 case Instruction::DOUBLE_TO_FLOAT:
buzbeee3acd072012-02-25 17:03:10 -0800616 genConversion(cUnit, mir);
617 break;
618
Elliott Hughesadb8c672012-03-06 16:49:32 -0800619 case Instruction::ADD_INT:
620 case Instruction::SUB_INT:
621 case Instruction::MUL_INT:
622 case Instruction::DIV_INT:
623 case Instruction::REM_INT:
624 case Instruction::AND_INT:
625 case Instruction::OR_INT:
626 case Instruction::XOR_INT:
627 case Instruction::SHL_INT:
628 case Instruction::SHR_INT:
629 case Instruction::USHR_INT:
630 case Instruction::ADD_INT_2ADDR:
631 case Instruction::SUB_INT_2ADDR:
632 case Instruction::MUL_INT_2ADDR:
633 case Instruction::DIV_INT_2ADDR:
634 case Instruction::REM_INT_2ADDR:
635 case Instruction::AND_INT_2ADDR:
636 case Instruction::OR_INT_2ADDR:
637 case Instruction::XOR_INT_2ADDR:
638 case Instruction::SHL_INT_2ADDR:
639 case Instruction::SHR_INT_2ADDR:
640 case Instruction::USHR_INT_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800641 genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
642 break;
643
Elliott Hughesadb8c672012-03-06 16:49:32 -0800644 case Instruction::ADD_LONG:
645 case Instruction::SUB_LONG:
646 case Instruction::MUL_LONG:
647 case Instruction::DIV_LONG:
648 case Instruction::REM_LONG:
649 case Instruction::AND_LONG:
650 case Instruction::OR_LONG:
651 case Instruction::XOR_LONG:
652 case Instruction::ADD_LONG_2ADDR:
653 case Instruction::SUB_LONG_2ADDR:
654 case Instruction::MUL_LONG_2ADDR:
655 case Instruction::DIV_LONG_2ADDR:
656 case Instruction::REM_LONG_2ADDR:
657 case Instruction::AND_LONG_2ADDR:
658 case Instruction::OR_LONG_2ADDR:
659 case Instruction::XOR_LONG_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800660 genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
661 break;
662
Elliott Hughesadb8c672012-03-06 16:49:32 -0800663 case Instruction::SHL_LONG:
664 case Instruction::SHR_LONG:
665 case Instruction::USHR_LONG:
666 case Instruction::SHL_LONG_2ADDR:
667 case Instruction::SHR_LONG_2ADDR:
668 case Instruction::USHR_LONG_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800669 genShiftOpLong(cUnit,mir, rlDest, rlSrc[0], rlSrc[1]);
670 break;
671
Elliott Hughesadb8c672012-03-06 16:49:32 -0800672 case Instruction::ADD_FLOAT:
673 case Instruction::SUB_FLOAT:
674 case Instruction::MUL_FLOAT:
675 case Instruction::DIV_FLOAT:
676 case Instruction::REM_FLOAT:
677 case Instruction::ADD_FLOAT_2ADDR:
678 case Instruction::SUB_FLOAT_2ADDR:
679 case Instruction::MUL_FLOAT_2ADDR:
680 case Instruction::DIV_FLOAT_2ADDR:
681 case Instruction::REM_FLOAT_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800682 genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
683 break;
684
Elliott Hughesadb8c672012-03-06 16:49:32 -0800685 case Instruction::ADD_DOUBLE:
686 case Instruction::SUB_DOUBLE:
687 case Instruction::MUL_DOUBLE:
688 case Instruction::DIV_DOUBLE:
689 case Instruction::REM_DOUBLE:
690 case Instruction::ADD_DOUBLE_2ADDR:
691 case Instruction::SUB_DOUBLE_2ADDR:
692 case Instruction::MUL_DOUBLE_2ADDR:
693 case Instruction::DIV_DOUBLE_2ADDR:
694 case Instruction::REM_DOUBLE_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800695 genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
696 break;
697
Elliott Hughesadb8c672012-03-06 16:49:32 -0800698 case Instruction::RSUB_INT:
699 case Instruction::ADD_INT_LIT16:
700 case Instruction::MUL_INT_LIT16:
701 case Instruction::DIV_INT_LIT16:
702 case Instruction::REM_INT_LIT16:
703 case Instruction::AND_INT_LIT16:
704 case Instruction::OR_INT_LIT16:
705 case Instruction::XOR_INT_LIT16:
706 case Instruction::ADD_INT_LIT8:
707 case Instruction::RSUB_INT_LIT8:
708 case Instruction::MUL_INT_LIT8:
709 case Instruction::DIV_INT_LIT8:
710 case Instruction::REM_INT_LIT8:
711 case Instruction::AND_INT_LIT8:
712 case Instruction::OR_INT_LIT8:
713 case Instruction::XOR_INT_LIT8:
714 case Instruction::SHL_INT_LIT8:
715 case Instruction::SHR_INT_LIT8:
716 case Instruction::USHR_INT_LIT8:
buzbeee3acd072012-02-25 17:03:10 -0800717 genArithOpIntLit(cUnit, mir, rlDest, rlSrc[0], mir->dalvikInsn.vC);
718 break;
719
720 default:
721 res = true;
722 }
723 return res;
724}
725
buzbee31a4a6f2012-02-28 15:36:15 -0800726const char* extendedMIROpNames[kMirOpLast - kMirOpFirst] = {
buzbeee3acd072012-02-25 17:03:10 -0800727 "kMirOpPhi",
728 "kMirOpNullNRangeUpCheck",
729 "kMirOpNullNRangeDownCheck",
730 "kMirOpLowerBound",
buzbeee1965672012-03-11 18:39:19 -0700731 "kMirOpCopy",
buzbeee3acd072012-02-25 17:03:10 -0800732};
733
734/* Extended MIR instructions like PHI */
buzbee31a4a6f2012-02-28 15:36:15 -0800735void handleExtendedMethodMIR(CompilationUnit* cUnit, MIR* mir)
buzbeee3acd072012-02-25 17:03:10 -0800736{
737 int opOffset = mir->dalvikInsn.opcode - kMirOpFirst;
738 char* msg = NULL;
739 if (cUnit->printMe) {
740 msg = (char*)oatNew(cUnit, strlen(extendedMIROpNames[opOffset]) + 1,
741 false, kAllocDebugInfo);
742 strcpy(msg, extendedMIROpNames[opOffset]);
743 }
buzbee31a4a6f2012-02-28 15:36:15 -0800744 LIR* op = newLIR1(cUnit, kPseudoExtended, (int) msg);
buzbeee3acd072012-02-25 17:03:10 -0800745
746 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
747 case kMirOpPhi: {
748 char* ssaString = NULL;
749 if (cUnit->printMe) {
750 ssaString = oatGetSSAString(cUnit, mir->ssaRep);
751 }
752 op->flags.isNop = true;
buzbee31a4a6f2012-02-28 15:36:15 -0800753 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
buzbeee3acd072012-02-25 17:03:10 -0800754 break;
755 }
buzbeee1965672012-03-11 18:39:19 -0700756 case kMirOpCopy:
757 UNIMPLEMENTED(FATAL) << "Need kMirOpCopy";
758 break;
buzbeee3acd072012-02-25 17:03:10 -0800759 default:
760 break;
761 }
762}
763
764/* Handle the content in each basic block */
buzbee31a4a6f2012-02-28 15:36:15 -0800765bool methodBlockCodeGen(CompilationUnit* cUnit, BasicBlock* bb)
buzbeee3acd072012-02-25 17:03:10 -0800766{
767 MIR* mir;
buzbee31a4a6f2012-02-28 15:36:15 -0800768 LIR* labelList = (LIR*) cUnit->blockLabelList;
buzbeee3acd072012-02-25 17:03:10 -0800769 int blockId = bb->id;
770
771 cUnit->curBlock = bb;
772 labelList[blockId].operands[0] = bb->startOffset;
773
774 /* Insert the block label */
buzbee31a4a6f2012-02-28 15:36:15 -0800775 labelList[blockId].opcode = kPseudoNormalBlockLabel;
buzbeee3acd072012-02-25 17:03:10 -0800776 oatAppendLIR(cUnit, (LIR*) &labelList[blockId]);
777
buzbeee1965672012-03-11 18:39:19 -0700778 /* Free temp registers and reset redundant store tracking */
buzbeee3acd072012-02-25 17:03:10 -0800779 oatResetRegPool(cUnit);
buzbeee3acd072012-02-25 17:03:10 -0800780 oatResetDefTracking(cUnit);
781
buzbeee1965672012-03-11 18:39:19 -0700782 /*
783 * If control reached us from our immediate predecessor via
784 * fallthrough and we have no other incoming arcs we can
785 * reuse existing liveness. Otherwise, reset.
786 */
787 if (!bb->fallThroughTarget || bb->predecessors->numUsed != 1) {
788 oatClobberAllRegs(cUnit);
789 }
790
buzbee31a4a6f2012-02-28 15:36:15 -0800791 LIR* headLIR = NULL;
buzbeee3acd072012-02-25 17:03:10 -0800792
793 if (bb->blockType == kEntryBlock) {
794 genEntrySequence(cUnit, bb);
795 } else if (bb->blockType == kExitBlock) {
796 genExitSequence(cUnit, bb);
797 }
798
799 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
800
801 oatResetRegPool(cUnit);
802 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
803 oatClobberAllRegs(cUnit);
804 }
805
806 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
807 oatResetDefTracking(cUnit);
808 }
809
buzbee3d661942012-03-14 17:37:27 -0700810#ifndef NDEBUG
811 /* Reset temp tracking sanity check */
812 cUnit->liveSReg = INVALID_SREG;
813#endif
814
buzbeee3acd072012-02-25 17:03:10 -0800815 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
816 handleExtendedMethodMIR(cUnit, mir);
817 continue;
818 }
819
820 cUnit->currentDalvikOffset = mir->offset;
821
Elliott Hughesadb8c672012-03-06 16:49:32 -0800822 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
823 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
buzbeee3acd072012-02-25 17:03:10 -0800824
buzbee31a4a6f2012-02-28 15:36:15 -0800825 LIR* boundaryLIR;
buzbeee3acd072012-02-25 17:03:10 -0800826
827 /* Mark the beginning of a Dalvik instruction for line tracking */
828 char* instStr = cUnit->printMe ?
Elliott Hughesadb8c672012-03-06 16:49:32 -0800829 oatGetDalvikDisassembly(cUnit, mir->dalvikInsn, "") : NULL;
buzbee31a4a6f2012-02-28 15:36:15 -0800830 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
buzbeee3acd072012-02-25 17:03:10 -0800831 (intptr_t) instStr);
832 cUnit->boundaryMap.insert(std::make_pair(mir->offset,
833 (LIR*)boundaryLIR));
834 /* Remember the first LIR for this block */
835 if (headLIR == NULL) {
836 headLIR = boundaryLIR;
837 /* Set the first boundaryLIR as a scheduling barrier */
838 headLIR->defMask = ENCODE_ALL;
839 }
840
841 /* If we're compiling for the debugger, generate an update callout */
842 if (cUnit->genDebugger) {
843 genDebuggerUpdate(cUnit, mir->offset);
844 }
845
846 /* Don't generate the SSA annotation unless verbose mode is on */
847 if (cUnit->printMe && mir->ssaRep) {
848 char* ssaString = oatGetSSAString(cUnit, mir->ssaRep);
buzbee31a4a6f2012-02-28 15:36:15 -0800849 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
buzbeee3acd072012-02-25 17:03:10 -0800850 }
851
852 bool notHandled = compileDalvikInstruction(cUnit, mir, bb, labelList);
buzbeee3acd072012-02-25 17:03:10 -0800853 if (notHandled) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800854 LOG(FATAL) << StringPrintf("%#06x: Opcode %#x (%s) / Fmt %d not handled",
855 mir->offset, dalvikOpcode, Instruction::Name(dalvikOpcode), dalvikFormat);
856
buzbeee3acd072012-02-25 17:03:10 -0800857 }
858 }
859
860 if (headLIR) {
861 /*
862 * Eliminate redundant loads/stores and delay stores into later
863 * slots
864 */
865 oatApplyLocalOptimizations(cUnit, (LIR*) headLIR,
866 cUnit->lastLIRInsn);
867
868 /*
869 * Generate an unconditional branch to the fallthrough block.
870 */
871 if (bb->fallThrough) {
buzbee82488f52012-03-02 08:20:26 -0800872 opUnconditionalBranch(cUnit,
873 &labelList[bb->fallThrough->id]);
buzbeee3acd072012-02-25 17:03:10 -0800874 }
875 }
876 return false;
877}
878
879void oatMethodMIR2LIR(CompilationUnit* cUnit)
880{
881 /* Used to hold the labels of each block */
882 cUnit->blockLabelList =
buzbee31a4a6f2012-02-28 15:36:15 -0800883 (void *) oatNew(cUnit, sizeof(LIR) * cUnit->numBlocks, true,
buzbeee3acd072012-02-25 17:03:10 -0800884 kAllocLIR);
885
886 oatDataFlowAnalysisDispatcher(cUnit, methodBlockCodeGen,
887 kPreOrderDFSTraversal, false /* Iterative */);
888 handleSuspendLaunchpads(cUnit);
889
890 handleThrowLaunchpads(cUnit);
891
buzbee86a4bce2012-03-06 18:15:00 -0800892 if (!(cUnit->disableOpt & (1 << kSafeOptimizations))) {
893 removeRedundantBranches(cUnit);
894 }
buzbeee3acd072012-02-25 17:03:10 -0800895}
896
897/* Needed by the ld/st optmizatons */
buzbee31a4a6f2012-02-28 15:36:15 -0800898LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
buzbeee3acd072012-02-25 17:03:10 -0800899{
buzbee82488f52012-03-02 08:20:26 -0800900 return opRegCopyNoInsert(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -0800901}
902
903/* Needed by the register allocator */
904void oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
905{
buzbee82488f52012-03-02 08:20:26 -0800906 opRegCopy(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -0800907}
908
909/* Needed by the register allocator */
910void oatRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
911 int srcLo, int srcHi)
912{
buzbee82488f52012-03-02 08:20:26 -0800913 opRegCopyWide(cUnit, destLo, destHi, srcLo, srcHi);
buzbeee3acd072012-02-25 17:03:10 -0800914}
915
916void oatFlushRegImpl(CompilationUnit* cUnit, int rBase,
917 int displacement, int rSrc, OpSize size)
918{
919 storeBaseDisp(cUnit, rBase, displacement, rSrc, size);
920}
921
922void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase,
923 int displacement, int rSrcLo, int rSrcHi)
924{
925 storeBaseDispWide(cUnit, rBase, displacement, rSrcLo, rSrcHi);
926}
927
928} // namespace art