blob: 59aa4caec41f7ae385d8dd89a3100b54c3dadd1e [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;
Ian Rogers2ed3b952012-03-17 11:49:39 -070073 uintptr_t directCode;
74 uintptr_t directMethod;
buzbeee3acd072012-02-25 17:03:10 -080075 bool skipThis;
76 bool fastPath =
Logan Chien4dd96f52012-02-29 01:26:58 +080077 cUnit->compiler->ComputeInvokeInfo(dexMethodIdx, &mUnit, type,
Ian Rogers2ed3b952012-03-17 11:49:39 -070078 vtableIdx, directCode,
79 directMethod)
buzbeee3acd072012-02-25 17:03:10 -080080 && !SLOW_INVOKE_PATH;
81 if (type == kInterface) {
82 nextCallInsn = fastPath ? nextInterfaceCallInsn
83 : nextInterfaceCallInsnWithAccessCheck;
84 skipThis = false;
85 } else if (type == kDirect) {
86 if (fastPath) {
87 pNullCk = &nullCk;
88 }
89 nextCallInsn = fastPath ? nextSDCallInsn : nextDirectCallInsnSP;
90 skipThis = false;
91 } else if (type == kStatic) {
92 nextCallInsn = fastPath ? nextSDCallInsn : nextStaticCallInsnSP;
93 skipThis = false;
94 } else if (type == kSuper) {
Ian Rogers2ed3b952012-03-17 11:49:39 -070095 DCHECK(!fastPath); // Fast path is a direct call.
96 nextCallInsn = nextSuperCallInsnSP;
97 skipThis = false;
buzbeee3acd072012-02-25 17:03:10 -080098 } else {
99 DCHECK_EQ(type, kVirtual);
100 nextCallInsn = fastPath ? nextVCallInsn : nextVCallInsnSP;
101 skipThis = fastPath;
102 }
103 if (!isRange) {
104 callState = genDalvikArgsNoRange(cUnit, mir, dInsn, callState, pNullCk,
105 nextCallInsn, dexMethodIdx,
Ian Rogers2ed3b952012-03-17 11:49:39 -0700106 vtableIdx, directCode, directMethod, skipThis);
buzbeee3acd072012-02-25 17:03:10 -0800107 } else {
108 callState = genDalvikArgsRange(cUnit, mir, dInsn, callState, pNullCk,
109 nextCallInsn, dexMethodIdx, vtableIdx,
Ian Rogers2ed3b952012-03-17 11:49:39 -0700110 directCode, directMethod, skipThis);
buzbeee3acd072012-02-25 17:03:10 -0800111 }
112 // Finish up any of the call sequence not interleaved in arg loading
113 while (callState >= 0) {
114 callState = nextCallInsn(cUnit, mir, callState, dexMethodIdx,
Ian Rogers2ed3b952012-03-17 11:49:39 -0700115 vtableIdx, directCode, directMethod);
buzbeee3acd072012-02-25 17:03:10 -0800116 }
117 if (DISPLAY_MISSING_TARGETS) {
118 genShowTarget(cUnit);
119 }
Ian Rogers6cbb2bd2012-03-16 13:45:30 -0700120#if !defined(TARGET_X86)
buzbee0398c422012-03-02 15:22:47 -0800121 opReg(cUnit, kOpBlx, rINVOKE_TGT);
Ian Rogers6cbb2bd2012-03-16 13:45:30 -0700122#else
123 if (fastPath) {
124 opMem(cUnit, kOpBlx, rARG0, Method::GetCodeOffset().Int32Value());
125 } else {
126 UNIMPLEMENTED(FATAL) << "compute trampoline";
127 opThreadMem(cUnit, kOpBlx, 0);
128 }
buzbeea7678db2012-03-05 15:35:46 -0800129#endif
Ian Rogers6cbb2bd2012-03-16 13:45:30 -0700130
131 oatClobberCalleeSave(cUnit);
buzbeee3acd072012-02-25 17:03:10 -0800132}
133
134/*
135 * Target-independent code generation. Use only high-level
136 * load/store utilities here, or target-dependent genXX() handlers
137 * when necessary.
138 */
buzbee31a4a6f2012-02-28 15:36:15 -0800139bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
140 BasicBlock* bb, LIR* labelList)
buzbeee3acd072012-02-25 17:03:10 -0800141{
142 bool res = false; // Assume success
143 RegLocation rlSrc[3];
144 RegLocation rlDest = badLoc;
145 RegLocation rlResult = badLoc;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800146 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbeee3acd072012-02-25 17:03:10 -0800147
148 /* Prep Src and Dest locations */
149 int nextSreg = 0;
150 int nextLoc = 0;
151 int attrs = oatDataFlowAttributes[opcode];
152 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
153 if (attrs & DF_UA) {
154 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
155 nextSreg++;
156 } else if (attrs & DF_UA_WIDE) {
157 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
158 nextSreg + 1);
159 nextSreg+= 2;
160 }
161 if (attrs & DF_UB) {
162 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
163 nextSreg++;
164 } else if (attrs & DF_UB_WIDE) {
165 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
166 nextSreg + 1);
167 nextSreg+= 2;
168 }
169 if (attrs & DF_UC) {
170 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
171 } else if (attrs & DF_UC_WIDE) {
172 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
173 nextSreg + 1);
174 }
175 if (attrs & DF_DA) {
176 rlDest = oatGetDest(cUnit, mir, 0);
177 } else if (attrs & DF_DA_WIDE) {
178 rlDest = oatGetDestWide(cUnit, mir, 0, 1);
179 }
180
181 switch(opcode) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800182 case Instruction::NOP:
buzbeee3acd072012-02-25 17:03:10 -0800183 break;
184
Elliott Hughesadb8c672012-03-06 16:49:32 -0800185 case Instruction::MOVE_EXCEPTION:
buzbeea7678db2012-03-05 15:35:46 -0800186#if defined(TARGET_X86)
Elliott Hughesadb8c672012-03-06 16:49:32 -0800187 UNIMPLEMENTED(WARNING) << "Instruction::MOVE_EXCEPTION";
buzbeea7678db2012-03-05 15:35:46 -0800188#else
buzbeee3acd072012-02-25 17:03:10 -0800189 int exOffset;
190 int resetReg;
191 exOffset = Thread::ExceptionOffset().Int32Value();
192 resetReg = oatAllocTemp(cUnit);
193 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
194 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
195 loadConstant(cUnit, resetReg, 0);
196 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
197 storeValue(cUnit, rlDest, rlResult);
buzbeea7678db2012-03-05 15:35:46 -0800198#endif
buzbeee3acd072012-02-25 17:03:10 -0800199 break;
200
Elliott Hughesadb8c672012-03-06 16:49:32 -0800201 case Instruction::RETURN_VOID:
buzbee86a4bce2012-03-06 18:15:00 -0800202 if (!cUnit->attrs & METHOD_IS_LEAF) {
203 genSuspendTest(cUnit, mir);
204 }
buzbeee3acd072012-02-25 17:03:10 -0800205 break;
206
Elliott Hughesadb8c672012-03-06 16:49:32 -0800207 case Instruction::RETURN:
208 case Instruction::RETURN_OBJECT:
buzbee86a4bce2012-03-06 18:15:00 -0800209 if (!cUnit->attrs & METHOD_IS_LEAF) {
210 genSuspendTest(cUnit, mir);
211 }
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700212 storeValue(cUnit, oatGetReturn(cUnit, cUnit->shorty[0] == 'F'),
213 rlSrc[0]);
buzbeee3acd072012-02-25 17:03:10 -0800214 break;
215
Elliott Hughesadb8c672012-03-06 16:49:32 -0800216 case Instruction::RETURN_WIDE:
buzbee86a4bce2012-03-06 18:15:00 -0800217 if (!cUnit->attrs & METHOD_IS_LEAF) {
218 genSuspendTest(cUnit, mir);
219 }
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700220 storeValueWide(cUnit, oatGetReturnWide(cUnit,
221 cUnit->shorty[0] == 'D'), rlSrc[0]);
buzbeee3acd072012-02-25 17:03:10 -0800222 break;
223
Elliott Hughesadb8c672012-03-06 16:49:32 -0800224 case Instruction::MOVE_RESULT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800225 if (mir->optimizationFlags & MIR_INLINED)
226 break; // Nop - combined w/ previous invoke
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700227 storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit, rlDest.fp));
buzbeee3acd072012-02-25 17:03:10 -0800228 break;
229
Elliott Hughesadb8c672012-03-06 16:49:32 -0800230 case Instruction::MOVE_RESULT:
231 case Instruction::MOVE_RESULT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800232 if (mir->optimizationFlags & MIR_INLINED)
233 break; // Nop - combined w/ previous invoke
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700234 storeValue(cUnit, rlDest, oatGetReturn(cUnit, rlDest.fp));
buzbeee3acd072012-02-25 17:03:10 -0800235 break;
236
Elliott Hughesadb8c672012-03-06 16:49:32 -0800237 case Instruction::MOVE:
238 case Instruction::MOVE_OBJECT:
239 case Instruction::MOVE_16:
240 case Instruction::MOVE_OBJECT_16:
241 case Instruction::MOVE_FROM16:
242 case Instruction::MOVE_OBJECT_FROM16:
buzbeee3acd072012-02-25 17:03:10 -0800243 storeValue(cUnit, rlDest, rlSrc[0]);
244 break;
245
Elliott Hughesadb8c672012-03-06 16:49:32 -0800246 case Instruction::MOVE_WIDE:
247 case Instruction::MOVE_WIDE_16:
248 case Instruction::MOVE_WIDE_FROM16:
buzbeee3acd072012-02-25 17:03:10 -0800249 storeValueWide(cUnit, rlDest, rlSrc[0]);
250 break;
251
Elliott Hughesadb8c672012-03-06 16:49:32 -0800252 case Instruction::CONST:
253 case Instruction::CONST_4:
254 case Instruction::CONST_16:
buzbeee3acd072012-02-25 17:03:10 -0800255 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
256 loadConstantNoClobber(cUnit, rlResult.lowReg, mir->dalvikInsn.vB);
257 storeValue(cUnit, rlDest, rlResult);
258 break;
259
Elliott Hughesadb8c672012-03-06 16:49:32 -0800260 case Instruction::CONST_HIGH16:
buzbeee3acd072012-02-25 17:03:10 -0800261 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
262 loadConstantNoClobber(cUnit, rlResult.lowReg,
263 mir->dalvikInsn.vB << 16);
264 storeValue(cUnit, rlDest, rlResult);
265 break;
266
Elliott Hughesadb8c672012-03-06 16:49:32 -0800267 case Instruction::CONST_WIDE_16:
268 case Instruction::CONST_WIDE_32:
buzbeee3acd072012-02-25 17:03:10 -0800269 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
270 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
271 mir->dalvikInsn.vB,
272 (mir->dalvikInsn.vB & 0x80000000) ? -1 : 0);
273 storeValueWide(cUnit, rlDest, rlResult);
274 break;
275
Elliott Hughesadb8c672012-03-06 16:49:32 -0800276 case Instruction::CONST_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800277 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
278 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
279 mir->dalvikInsn.vB_wide & 0xffffffff,
280 (mir->dalvikInsn.vB_wide >> 32) & 0xffffffff);
281 storeValueWide(cUnit, rlDest, rlResult);
282 break;
283
Elliott Hughesadb8c672012-03-06 16:49:32 -0800284 case Instruction::CONST_WIDE_HIGH16:
buzbeee3acd072012-02-25 17:03:10 -0800285 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
286 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
287 0, mir->dalvikInsn.vB << 16);
288 storeValueWide(cUnit, rlDest, rlResult);
289 break;
290
Elliott Hughesadb8c672012-03-06 16:49:32 -0800291 case Instruction::MONITOR_ENTER:
buzbeee3acd072012-02-25 17:03:10 -0800292 genMonitorEnter(cUnit, mir, rlSrc[0]);
293 break;
294
Elliott Hughesadb8c672012-03-06 16:49:32 -0800295 case Instruction::MONITOR_EXIT:
buzbeee3acd072012-02-25 17:03:10 -0800296 genMonitorExit(cUnit, mir, rlSrc[0]);
297 break;
298
Elliott Hughesadb8c672012-03-06 16:49:32 -0800299 case Instruction::CHECK_CAST:
buzbeee3acd072012-02-25 17:03:10 -0800300 genCheckCast(cUnit, mir, rlSrc[0]);
301 break;
302
Elliott Hughesadb8c672012-03-06 16:49:32 -0800303 case Instruction::INSTANCE_OF:
buzbeee3acd072012-02-25 17:03:10 -0800304 genInstanceof(cUnit, mir, rlDest, rlSrc[0]);
305 break;
306
Elliott Hughesadb8c672012-03-06 16:49:32 -0800307 case Instruction::NEW_INSTANCE:
buzbeee3acd072012-02-25 17:03:10 -0800308 genNewInstance(cUnit, mir, rlDest);
309 break;
310
Elliott Hughesadb8c672012-03-06 16:49:32 -0800311 case Instruction::THROW:
buzbeee3acd072012-02-25 17:03:10 -0800312 genThrow(cUnit, mir, rlSrc[0]);
313 break;
314
Elliott Hughesadb8c672012-03-06 16:49:32 -0800315 case Instruction::THROW_VERIFICATION_ERROR:
buzbeee3acd072012-02-25 17:03:10 -0800316 genThrowVerificationError(cUnit, mir);
317 break;
318
Elliott Hughesadb8c672012-03-06 16:49:32 -0800319 case Instruction::ARRAY_LENGTH:
buzbeee3acd072012-02-25 17:03:10 -0800320 int lenOffset;
321 lenOffset = Array::LengthOffset().Int32Value();
322 rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
323 genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, mir);
324 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
325 loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset,
326 rlResult.lowReg);
327 storeValue(cUnit, rlDest, rlResult);
328 break;
329
Elliott Hughesadb8c672012-03-06 16:49:32 -0800330 case Instruction::CONST_STRING:
331 case Instruction::CONST_STRING_JUMBO:
buzbeee3acd072012-02-25 17:03:10 -0800332 genConstString(cUnit, mir, rlDest, rlSrc[0]);
333 break;
334
Elliott Hughesadb8c672012-03-06 16:49:32 -0800335 case Instruction::CONST_CLASS:
buzbeee3acd072012-02-25 17:03:10 -0800336 genConstClass(cUnit, mir, rlDest, rlSrc[0]);
337 break;
338
Elliott Hughesadb8c672012-03-06 16:49:32 -0800339 case Instruction::FILL_ARRAY_DATA:
buzbeee3acd072012-02-25 17:03:10 -0800340 genFillArrayData(cUnit, mir, rlSrc[0]);
341 break;
342
Elliott Hughesadb8c672012-03-06 16:49:32 -0800343 case Instruction::FILLED_NEW_ARRAY:
buzbeee3acd072012-02-25 17:03:10 -0800344 genFilledNewArray(cUnit, mir, false /* not range */);
345 break;
346
Elliott Hughesadb8c672012-03-06 16:49:32 -0800347 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800348 genFilledNewArray(cUnit, mir, true /* range */);
349 break;
350
Elliott Hughesadb8c672012-03-06 16:49:32 -0800351 case Instruction::NEW_ARRAY:
buzbeee3acd072012-02-25 17:03:10 -0800352 genNewArray(cUnit, mir, rlDest, rlSrc[0]);
353 break;
354
Elliott Hughesadb8c672012-03-06 16:49:32 -0800355 case Instruction::GOTO:
356 case Instruction::GOTO_16:
357 case Instruction::GOTO_32:
buzbeee3acd072012-02-25 17:03:10 -0800358 if (bb->taken->startOffset <= mir->offset) {
359 genSuspendTest(cUnit, mir);
360 }
buzbee82488f52012-03-02 08:20:26 -0800361 opUnconditionalBranch(cUnit, &labelList[bb->taken->id]);
buzbeee3acd072012-02-25 17:03:10 -0800362 break;
363
Elliott Hughesadb8c672012-03-06 16:49:32 -0800364 case Instruction::PACKED_SWITCH:
buzbeee3acd072012-02-25 17:03:10 -0800365 genPackedSwitch(cUnit, mir, rlSrc[0]);
366 break;
367
Elliott Hughesadb8c672012-03-06 16:49:32 -0800368 case Instruction::SPARSE_SWITCH:
buzbeee3acd072012-02-25 17:03:10 -0800369 genSparseSwitch(cUnit, mir, rlSrc[0]);
370 break;
371
Elliott Hughesadb8c672012-03-06 16:49:32 -0800372 case Instruction::CMPL_FLOAT:
373 case Instruction::CMPG_FLOAT:
374 case Instruction::CMPL_DOUBLE:
375 case Instruction::CMPG_DOUBLE:
buzbeee3acd072012-02-25 17:03:10 -0800376 res = genCmpFP(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
377 break;
378
Elliott Hughesadb8c672012-03-06 16:49:32 -0800379 case Instruction::CMP_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800380 genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
381 break;
382
Elliott Hughesadb8c672012-03-06 16:49:32 -0800383 case Instruction::IF_EQ:
384 case Instruction::IF_NE:
385 case Instruction::IF_LT:
386 case Instruction::IF_GE:
387 case Instruction::IF_GT:
388 case Instruction::IF_LE: {
buzbeee3acd072012-02-25 17:03:10 -0800389 bool backwardBranch;
390 backwardBranch = (bb->taken->startOffset <= mir->offset);
391 if (backwardBranch) {
392 genSuspendTest(cUnit, mir);
393 }
394 genCompareAndBranch(cUnit, bb, mir, rlSrc[0], rlSrc[1], labelList);
395 break;
396 }
397
Elliott Hughesadb8c672012-03-06 16:49:32 -0800398 case Instruction::IF_EQZ:
399 case Instruction::IF_NEZ:
400 case Instruction::IF_LTZ:
401 case Instruction::IF_GEZ:
402 case Instruction::IF_GTZ:
403 case Instruction::IF_LEZ: {
buzbeee3acd072012-02-25 17:03:10 -0800404 bool backwardBranch;
405 backwardBranch = (bb->taken->startOffset <= mir->offset);
406 if (backwardBranch) {
407 genSuspendTest(cUnit, mir);
408 }
409 genCompareZeroAndBranch(cUnit, bb, mir, rlSrc[0], labelList);
410 break;
411 }
412
Elliott Hughesadb8c672012-03-06 16:49:32 -0800413 case Instruction::AGET_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800414 genArrayGet(cUnit, mir, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
415 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800416 case Instruction::AGET:
417 case Instruction::AGET_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800418 genArrayGet(cUnit, mir, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
419 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800420 case Instruction::AGET_BOOLEAN:
buzbeee3acd072012-02-25 17:03:10 -0800421 genArrayGet(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1],
422 rlDest, 0);
423 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800424 case Instruction::AGET_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800425 genArrayGet(cUnit, mir, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
426 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800427 case Instruction::AGET_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800428 genArrayGet(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1],
429 rlDest, 1);
430 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800431 case Instruction::AGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800432 genArrayGet(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
433 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800434 case Instruction::APUT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800435 genArrayPut(cUnit, mir, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
436 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800437 case Instruction::APUT:
buzbeee3acd072012-02-25 17:03:10 -0800438 genArrayPut(cUnit, mir, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
439 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800440 case Instruction::APUT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800441 genArrayObjPut(cUnit, mir, rlSrc[1], rlSrc[2], rlSrc[0], 2);
442 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800443 case Instruction::APUT_SHORT:
444 case Instruction::APUT_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800445 genArrayPut(cUnit, mir, kUnsignedHalf, rlSrc[1], rlSrc[2],
446 rlSrc[0], 1);
447 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800448 case Instruction::APUT_BYTE:
449 case Instruction::APUT_BOOLEAN:
buzbeee3acd072012-02-25 17:03:10 -0800450 genArrayPut(cUnit, mir, kUnsignedByte, rlSrc[1], rlSrc[2],
451 rlSrc[0], 0);
452 break;
453
Elliott Hughesadb8c672012-03-06 16:49:32 -0800454 case Instruction::IGET_OBJECT:
455 //case Instruction::IGET_OBJECT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800456 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, true);
457 break;
458
Elliott Hughesadb8c672012-03-06 16:49:32 -0800459 case Instruction::IGET_WIDE:
460 //case Instruction::IGET_WIDE_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800461 genIGet(cUnit, mir, kLong, rlDest, rlSrc[0], true, false);
462 break;
463
Elliott Hughesadb8c672012-03-06 16:49:32 -0800464 case Instruction::IGET:
465 //case Instruction::IGET_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800466 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, false);
467 break;
468
Elliott Hughesadb8c672012-03-06 16:49:32 -0800469 case Instruction::IGET_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800470 genIGet(cUnit, mir, kUnsignedHalf, rlDest, rlSrc[0], false, false);
471 break;
472
Elliott Hughesadb8c672012-03-06 16:49:32 -0800473 case Instruction::IGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800474 genIGet(cUnit, mir, kSignedHalf, rlDest, rlSrc[0], false, false);
475 break;
476
Elliott Hughesadb8c672012-03-06 16:49:32 -0800477 case Instruction::IGET_BOOLEAN:
478 case Instruction::IGET_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800479 genIGet(cUnit, mir, kUnsignedByte, rlDest, rlSrc[0], false, false);
480 break;
481
Elliott Hughesadb8c672012-03-06 16:49:32 -0800482 case Instruction::IPUT_WIDE:
483 //case Instruction::IPUT_WIDE_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800484 genIPut(cUnit, mir, kLong, rlSrc[0], rlSrc[1], true, false);
485 break;
486
Elliott Hughesadb8c672012-03-06 16:49:32 -0800487 case Instruction::IPUT_OBJECT:
488 //case Instruction::IPUT_OBJECT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800489 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, true);
490 break;
491
Elliott Hughesadb8c672012-03-06 16:49:32 -0800492 case Instruction::IPUT:
493 //case Instruction::IPUT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800494 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, false);
495 break;
496
Elliott Hughesadb8c672012-03-06 16:49:32 -0800497 case Instruction::IPUT_BOOLEAN:
498 case Instruction::IPUT_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800499 genIPut(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
500 break;
501
Elliott Hughesadb8c672012-03-06 16:49:32 -0800502 case Instruction::IPUT_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800503 genIPut(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
504 break;
505
Elliott Hughesadb8c672012-03-06 16:49:32 -0800506 case Instruction::IPUT_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800507 genIPut(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
508 break;
509
Elliott Hughesadb8c672012-03-06 16:49:32 -0800510 case Instruction::SGET_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800511 genSget(cUnit, mir, rlDest, false, true);
512 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800513 case Instruction::SGET:
514 case Instruction::SGET_BOOLEAN:
515 case Instruction::SGET_BYTE:
516 case Instruction::SGET_CHAR:
517 case Instruction::SGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800518 genSget(cUnit, mir, rlDest, false, false);
519 break;
520
Elliott Hughesadb8c672012-03-06 16:49:32 -0800521 case Instruction::SGET_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800522 genSget(cUnit, mir, rlDest, true, false);
523 break;
524
Elliott Hughesadb8c672012-03-06 16:49:32 -0800525 case Instruction::SPUT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800526 genSput(cUnit, mir, rlSrc[0], false, true);
527 break;
528
Elliott Hughesadb8c672012-03-06 16:49:32 -0800529 case Instruction::SPUT:
530 case Instruction::SPUT_BOOLEAN:
531 case Instruction::SPUT_BYTE:
532 case Instruction::SPUT_CHAR:
533 case Instruction::SPUT_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800534 genSput(cUnit, mir, rlSrc[0], false, false);
535 break;
536
Elliott Hughesadb8c672012-03-06 16:49:32 -0800537 case Instruction::SPUT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800538 genSput(cUnit, mir, rlSrc[0], true, false);
539 break;
540
Elliott Hughesadb8c672012-03-06 16:49:32 -0800541 case Instruction::INVOKE_STATIC_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800542 genInvoke(cUnit, mir, kStatic, true /*range*/);
543 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800544 case Instruction::INVOKE_STATIC:
buzbeee3acd072012-02-25 17:03:10 -0800545 genInvoke(cUnit, mir, kStatic, false /*range*/);
546 break;
547
Elliott Hughesadb8c672012-03-06 16:49:32 -0800548 case Instruction::INVOKE_DIRECT:
buzbeee3acd072012-02-25 17:03:10 -0800549 genInvoke(cUnit, mir, kDirect, false /*range*/);
550 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800551 case Instruction::INVOKE_DIRECT_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800552 genInvoke(cUnit, mir, kDirect, true /*range*/);
553 break;
554
Elliott Hughesadb8c672012-03-06 16:49:32 -0800555 case Instruction::INVOKE_VIRTUAL:
buzbeee3acd072012-02-25 17:03:10 -0800556 genInvoke(cUnit, mir, kVirtual, false /*range*/);
557 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800558 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800559 genInvoke(cUnit, mir, kVirtual, true /*range*/);
560 break;
561
Elliott Hughesadb8c672012-03-06 16:49:32 -0800562 case Instruction::INVOKE_SUPER:
buzbeee3acd072012-02-25 17:03:10 -0800563 genInvoke(cUnit, mir, kSuper, false /*range*/);
564 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800565 case Instruction::INVOKE_SUPER_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800566 genInvoke(cUnit, mir, kSuper, true /*range*/);
567 break;
568
Elliott Hughesadb8c672012-03-06 16:49:32 -0800569 case Instruction::INVOKE_INTERFACE:
buzbeee3acd072012-02-25 17:03:10 -0800570 genInvoke(cUnit, mir, kInterface, false /*range*/);
571 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800572 case Instruction::INVOKE_INTERFACE_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800573 genInvoke(cUnit, mir, kInterface, true /*range*/);
574 break;
575
Elliott Hughesadb8c672012-03-06 16:49:32 -0800576 case Instruction::NEG_INT:
577 case Instruction::NOT_INT:
buzbeee3acd072012-02-25 17:03:10 -0800578 res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
579 break;
580
Elliott Hughesadb8c672012-03-06 16:49:32 -0800581 case Instruction::NEG_LONG:
582 case Instruction::NOT_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800583 res = genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
584 break;
585
Elliott Hughesadb8c672012-03-06 16:49:32 -0800586 case Instruction::NEG_FLOAT:
buzbeee3acd072012-02-25 17:03:10 -0800587 res = genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
588 break;
589
Elliott Hughesadb8c672012-03-06 16:49:32 -0800590 case Instruction::NEG_DOUBLE:
buzbeee3acd072012-02-25 17:03:10 -0800591 res = genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
592 break;
593
Elliott Hughesadb8c672012-03-06 16:49:32 -0800594 case Instruction::INT_TO_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800595 genIntToLong(cUnit, mir, rlDest, rlSrc[0]);
596 break;
597
Elliott Hughesadb8c672012-03-06 16:49:32 -0800598 case Instruction::LONG_TO_INT:
buzbeee3acd072012-02-25 17:03:10 -0800599 rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
600 rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
601 storeValue(cUnit, rlDest, rlSrc[0]);
602 break;
603
Elliott Hughesadb8c672012-03-06 16:49:32 -0800604 case Instruction::INT_TO_BYTE:
605 case Instruction::INT_TO_SHORT:
606 case Instruction::INT_TO_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800607 genIntNarrowing(cUnit, mir, rlDest, rlSrc[0]);
608 break;
609
Elliott Hughesadb8c672012-03-06 16:49:32 -0800610 case Instruction::INT_TO_FLOAT:
611 case Instruction::INT_TO_DOUBLE:
612 case Instruction::LONG_TO_FLOAT:
613 case Instruction::LONG_TO_DOUBLE:
614 case Instruction::FLOAT_TO_INT:
615 case Instruction::FLOAT_TO_LONG:
616 case Instruction::FLOAT_TO_DOUBLE:
617 case Instruction::DOUBLE_TO_INT:
618 case Instruction::DOUBLE_TO_LONG:
619 case Instruction::DOUBLE_TO_FLOAT:
buzbeee3acd072012-02-25 17:03:10 -0800620 genConversion(cUnit, mir);
621 break;
622
Elliott Hughesadb8c672012-03-06 16:49:32 -0800623 case Instruction::ADD_INT:
624 case Instruction::SUB_INT:
625 case Instruction::MUL_INT:
626 case Instruction::DIV_INT:
627 case Instruction::REM_INT:
628 case Instruction::AND_INT:
629 case Instruction::OR_INT:
630 case Instruction::XOR_INT:
631 case Instruction::SHL_INT:
632 case Instruction::SHR_INT:
633 case Instruction::USHR_INT:
634 case Instruction::ADD_INT_2ADDR:
635 case Instruction::SUB_INT_2ADDR:
636 case Instruction::MUL_INT_2ADDR:
637 case Instruction::DIV_INT_2ADDR:
638 case Instruction::REM_INT_2ADDR:
639 case Instruction::AND_INT_2ADDR:
640 case Instruction::OR_INT_2ADDR:
641 case Instruction::XOR_INT_2ADDR:
642 case Instruction::SHL_INT_2ADDR:
643 case Instruction::SHR_INT_2ADDR:
644 case Instruction::USHR_INT_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800645 genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
646 break;
647
Elliott Hughesadb8c672012-03-06 16:49:32 -0800648 case Instruction::ADD_LONG:
649 case Instruction::SUB_LONG:
650 case Instruction::MUL_LONG:
651 case Instruction::DIV_LONG:
652 case Instruction::REM_LONG:
653 case Instruction::AND_LONG:
654 case Instruction::OR_LONG:
655 case Instruction::XOR_LONG:
656 case Instruction::ADD_LONG_2ADDR:
657 case Instruction::SUB_LONG_2ADDR:
658 case Instruction::MUL_LONG_2ADDR:
659 case Instruction::DIV_LONG_2ADDR:
660 case Instruction::REM_LONG_2ADDR:
661 case Instruction::AND_LONG_2ADDR:
662 case Instruction::OR_LONG_2ADDR:
663 case Instruction::XOR_LONG_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800664 genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
665 break;
666
Elliott Hughesadb8c672012-03-06 16:49:32 -0800667 case Instruction::SHL_LONG:
668 case Instruction::SHR_LONG:
669 case Instruction::USHR_LONG:
670 case Instruction::SHL_LONG_2ADDR:
671 case Instruction::SHR_LONG_2ADDR:
672 case Instruction::USHR_LONG_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800673 genShiftOpLong(cUnit,mir, rlDest, rlSrc[0], rlSrc[1]);
674 break;
675
Elliott Hughesadb8c672012-03-06 16:49:32 -0800676 case Instruction::ADD_FLOAT:
677 case Instruction::SUB_FLOAT:
678 case Instruction::MUL_FLOAT:
679 case Instruction::DIV_FLOAT:
680 case Instruction::REM_FLOAT:
681 case Instruction::ADD_FLOAT_2ADDR:
682 case Instruction::SUB_FLOAT_2ADDR:
683 case Instruction::MUL_FLOAT_2ADDR:
684 case Instruction::DIV_FLOAT_2ADDR:
685 case Instruction::REM_FLOAT_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800686 genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
687 break;
688
Elliott Hughesadb8c672012-03-06 16:49:32 -0800689 case Instruction::ADD_DOUBLE:
690 case Instruction::SUB_DOUBLE:
691 case Instruction::MUL_DOUBLE:
692 case Instruction::DIV_DOUBLE:
693 case Instruction::REM_DOUBLE:
694 case Instruction::ADD_DOUBLE_2ADDR:
695 case Instruction::SUB_DOUBLE_2ADDR:
696 case Instruction::MUL_DOUBLE_2ADDR:
697 case Instruction::DIV_DOUBLE_2ADDR:
698 case Instruction::REM_DOUBLE_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800699 genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
700 break;
701
Elliott Hughesadb8c672012-03-06 16:49:32 -0800702 case Instruction::RSUB_INT:
703 case Instruction::ADD_INT_LIT16:
704 case Instruction::MUL_INT_LIT16:
705 case Instruction::DIV_INT_LIT16:
706 case Instruction::REM_INT_LIT16:
707 case Instruction::AND_INT_LIT16:
708 case Instruction::OR_INT_LIT16:
709 case Instruction::XOR_INT_LIT16:
710 case Instruction::ADD_INT_LIT8:
711 case Instruction::RSUB_INT_LIT8:
712 case Instruction::MUL_INT_LIT8:
713 case Instruction::DIV_INT_LIT8:
714 case Instruction::REM_INT_LIT8:
715 case Instruction::AND_INT_LIT8:
716 case Instruction::OR_INT_LIT8:
717 case Instruction::XOR_INT_LIT8:
718 case Instruction::SHL_INT_LIT8:
719 case Instruction::SHR_INT_LIT8:
720 case Instruction::USHR_INT_LIT8:
buzbeee3acd072012-02-25 17:03:10 -0800721 genArithOpIntLit(cUnit, mir, rlDest, rlSrc[0], mir->dalvikInsn.vC);
722 break;
723
724 default:
725 res = true;
726 }
727 return res;
728}
729
buzbee31a4a6f2012-02-28 15:36:15 -0800730const char* extendedMIROpNames[kMirOpLast - kMirOpFirst] = {
buzbeee3acd072012-02-25 17:03:10 -0800731 "kMirOpPhi",
732 "kMirOpNullNRangeUpCheck",
733 "kMirOpNullNRangeDownCheck",
734 "kMirOpLowerBound",
buzbeee1965672012-03-11 18:39:19 -0700735 "kMirOpCopy",
buzbeee3acd072012-02-25 17:03:10 -0800736};
737
738/* Extended MIR instructions like PHI */
buzbee31a4a6f2012-02-28 15:36:15 -0800739void handleExtendedMethodMIR(CompilationUnit* cUnit, MIR* mir)
buzbeee3acd072012-02-25 17:03:10 -0800740{
741 int opOffset = mir->dalvikInsn.opcode - kMirOpFirst;
742 char* msg = NULL;
743 if (cUnit->printMe) {
744 msg = (char*)oatNew(cUnit, strlen(extendedMIROpNames[opOffset]) + 1,
745 false, kAllocDebugInfo);
746 strcpy(msg, extendedMIROpNames[opOffset]);
747 }
buzbee31a4a6f2012-02-28 15:36:15 -0800748 LIR* op = newLIR1(cUnit, kPseudoExtended, (int) msg);
buzbeee3acd072012-02-25 17:03:10 -0800749
750 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
751 case kMirOpPhi: {
752 char* ssaString = NULL;
753 if (cUnit->printMe) {
754 ssaString = oatGetSSAString(cUnit, mir->ssaRep);
755 }
756 op->flags.isNop = true;
buzbee31a4a6f2012-02-28 15:36:15 -0800757 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
buzbeee3acd072012-02-25 17:03:10 -0800758 break;
759 }
buzbee239c4e72012-03-16 08:42:29 -0700760 case kMirOpCopy: {
761 RegLocation rlSrc = oatGetSrc(cUnit, mir, 0);
762 RegLocation rlDest = oatGetDest(cUnit, mir, 0);
763 storeValue(cUnit, rlDest, rlSrc);
buzbeee1965672012-03-11 18:39:19 -0700764 break;
buzbee239c4e72012-03-16 08:42:29 -0700765 }
buzbeee3acd072012-02-25 17:03:10 -0800766 default:
767 break;
768 }
769}
770
771/* Handle the content in each basic block */
buzbee31a4a6f2012-02-28 15:36:15 -0800772bool methodBlockCodeGen(CompilationUnit* cUnit, BasicBlock* bb)
buzbeee3acd072012-02-25 17:03:10 -0800773{
774 MIR* mir;
buzbee31a4a6f2012-02-28 15:36:15 -0800775 LIR* labelList = (LIR*) cUnit->blockLabelList;
buzbeee3acd072012-02-25 17:03:10 -0800776 int blockId = bb->id;
777
778 cUnit->curBlock = bb;
779 labelList[blockId].operands[0] = bb->startOffset;
780
781 /* Insert the block label */
buzbee31a4a6f2012-02-28 15:36:15 -0800782 labelList[blockId].opcode = kPseudoNormalBlockLabel;
buzbeee3acd072012-02-25 17:03:10 -0800783 oatAppendLIR(cUnit, (LIR*) &labelList[blockId]);
784
buzbeee1965672012-03-11 18:39:19 -0700785 /* Free temp registers and reset redundant store tracking */
buzbeee3acd072012-02-25 17:03:10 -0800786 oatResetRegPool(cUnit);
buzbeee3acd072012-02-25 17:03:10 -0800787 oatResetDefTracking(cUnit);
788
buzbeee1965672012-03-11 18:39:19 -0700789 /*
790 * If control reached us from our immediate predecessor via
791 * fallthrough and we have no other incoming arcs we can
792 * reuse existing liveness. Otherwise, reset.
793 */
794 if (!bb->fallThroughTarget || bb->predecessors->numUsed != 1) {
795 oatClobberAllRegs(cUnit);
796 }
797
buzbee31a4a6f2012-02-28 15:36:15 -0800798 LIR* headLIR = NULL;
buzbeee3acd072012-02-25 17:03:10 -0800799
800 if (bb->blockType == kEntryBlock) {
801 genEntrySequence(cUnit, bb);
802 } else if (bb->blockType == kExitBlock) {
803 genExitSequence(cUnit, bb);
804 }
805
806 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
807
808 oatResetRegPool(cUnit);
809 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
810 oatClobberAllRegs(cUnit);
811 }
812
813 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
814 oatResetDefTracking(cUnit);
815 }
816
buzbee3d661942012-03-14 17:37:27 -0700817#ifndef NDEBUG
818 /* Reset temp tracking sanity check */
819 cUnit->liveSReg = INVALID_SREG;
820#endif
821
buzbeee3acd072012-02-25 17:03:10 -0800822 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
823 handleExtendedMethodMIR(cUnit, mir);
824 continue;
825 }
826
827 cUnit->currentDalvikOffset = mir->offset;
828
Elliott Hughesadb8c672012-03-06 16:49:32 -0800829 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
830 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
buzbeee3acd072012-02-25 17:03:10 -0800831
buzbee31a4a6f2012-02-28 15:36:15 -0800832 LIR* boundaryLIR;
buzbeee3acd072012-02-25 17:03:10 -0800833
834 /* Mark the beginning of a Dalvik instruction for line tracking */
835 char* instStr = cUnit->printMe ?
Elliott Hughesadb8c672012-03-06 16:49:32 -0800836 oatGetDalvikDisassembly(cUnit, mir->dalvikInsn, "") : NULL;
buzbee31a4a6f2012-02-28 15:36:15 -0800837 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
buzbeee3acd072012-02-25 17:03:10 -0800838 (intptr_t) instStr);
839 cUnit->boundaryMap.insert(std::make_pair(mir->offset,
840 (LIR*)boundaryLIR));
841 /* Remember the first LIR for this block */
842 if (headLIR == NULL) {
843 headLIR = boundaryLIR;
844 /* Set the first boundaryLIR as a scheduling barrier */
845 headLIR->defMask = ENCODE_ALL;
846 }
847
848 /* If we're compiling for the debugger, generate an update callout */
849 if (cUnit->genDebugger) {
850 genDebuggerUpdate(cUnit, mir->offset);
851 }
852
853 /* Don't generate the SSA annotation unless verbose mode is on */
854 if (cUnit->printMe && mir->ssaRep) {
855 char* ssaString = oatGetSSAString(cUnit, mir->ssaRep);
buzbee31a4a6f2012-02-28 15:36:15 -0800856 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
buzbeee3acd072012-02-25 17:03:10 -0800857 }
858
859 bool notHandled = compileDalvikInstruction(cUnit, mir, bb, labelList);
buzbeee3acd072012-02-25 17:03:10 -0800860 if (notHandled) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800861 LOG(FATAL) << StringPrintf("%#06x: Opcode %#x (%s) / Fmt %d not handled",
862 mir->offset, dalvikOpcode, Instruction::Name(dalvikOpcode), dalvikFormat);
863
buzbeee3acd072012-02-25 17:03:10 -0800864 }
865 }
866
867 if (headLIR) {
868 /*
869 * Eliminate redundant loads/stores and delay stores into later
870 * slots
871 */
872 oatApplyLocalOptimizations(cUnit, (LIR*) headLIR,
873 cUnit->lastLIRInsn);
874
875 /*
876 * Generate an unconditional branch to the fallthrough block.
877 */
878 if (bb->fallThrough) {
buzbee82488f52012-03-02 08:20:26 -0800879 opUnconditionalBranch(cUnit,
880 &labelList[bb->fallThrough->id]);
buzbeee3acd072012-02-25 17:03:10 -0800881 }
882 }
883 return false;
884}
885
886void oatMethodMIR2LIR(CompilationUnit* cUnit)
887{
888 /* Used to hold the labels of each block */
889 cUnit->blockLabelList =
buzbee31a4a6f2012-02-28 15:36:15 -0800890 (void *) oatNew(cUnit, sizeof(LIR) * cUnit->numBlocks, true,
buzbeee3acd072012-02-25 17:03:10 -0800891 kAllocLIR);
892
893 oatDataFlowAnalysisDispatcher(cUnit, methodBlockCodeGen,
894 kPreOrderDFSTraversal, false /* Iterative */);
Ian Rogersab2b55d2012-03-18 00:06:11 -0700895
buzbeee3acd072012-02-25 17:03:10 -0800896 handleSuspendLaunchpads(cUnit);
897
898 handleThrowLaunchpads(cUnit);
899
buzbee86a4bce2012-03-06 18:15:00 -0800900 if (!(cUnit->disableOpt & (1 << kSafeOptimizations))) {
901 removeRedundantBranches(cUnit);
902 }
buzbeee3acd072012-02-25 17:03:10 -0800903}
904
905/* Needed by the ld/st optmizatons */
buzbee31a4a6f2012-02-28 15:36:15 -0800906LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
buzbeee3acd072012-02-25 17:03:10 -0800907{
buzbee82488f52012-03-02 08:20:26 -0800908 return opRegCopyNoInsert(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -0800909}
910
911/* Needed by the register allocator */
912void oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
913{
buzbee82488f52012-03-02 08:20:26 -0800914 opRegCopy(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -0800915}
916
917/* Needed by the register allocator */
918void oatRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
919 int srcLo, int srcHi)
920{
buzbee82488f52012-03-02 08:20:26 -0800921 opRegCopyWide(cUnit, destLo, destHi, srcLo, srcHi);
buzbeee3acd072012-02-25 17:03:10 -0800922}
923
924void oatFlushRegImpl(CompilationUnit* cUnit, int rBase,
925 int displacement, int rSrc, OpSize size)
926{
927 storeBaseDisp(cUnit, rBase, displacement, rSrc, size);
928}
929
930void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase,
931 int displacement, int rSrcLo, int rSrcHi)
932{
933 storeBaseDispWide(cUnit, rBase, displacement, rSrcLo, rSrcHi);
934}
935
936} // namespace art