blob: db491f18366ae2d6dd097295fe738357ced755fc [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 */
buzbee86a4bce2012-03-06 18:15:00 -080028RegLocation oatGetReturnWide(CompilationUnit* cUnit)
buzbeee3acd072012-02-25 17:03:10 -080029{
30 RegLocation res = LOC_C_RETURN_WIDE;
buzbee86a4bce2012-03-06 18:15:00 -080031 oatClobber(cUnit, res.lowReg);
32 oatClobber(cUnit, res.highReg);
buzbeee3acd072012-02-25 17:03:10 -080033 oatLockTemp(cUnit, res.lowReg);
34 oatLockTemp(cUnit, res.highReg);
35 oatMarkPair(cUnit, res.lowReg, res.highReg);
36 return res;
37}
38
buzbee86a4bce2012-03-06 18:15:00 -080039RegLocation oatGetReturn(CompilationUnit* cUnit)
buzbeee3acd072012-02-25 17:03:10 -080040{
41 RegLocation res = LOC_C_RETURN;
buzbee86a4bce2012-03-06 18:15:00 -080042 oatClobber(cUnit, res.lowReg);
buzbeee3acd072012-02-25 17:03:10 -080043 oatLockTemp(cUnit, res.lowReg);
44 return res;
45}
46
buzbee31a4a6f2012-02-28 15:36:15 -080047void genInvoke(CompilationUnit* cUnit, MIR* mir, InvokeType type, bool isRange)
buzbeee3acd072012-02-25 17:03:10 -080048{
buzbeea7678db2012-03-05 15:35:46 -080049#if defined(TARGET_X86)
50 UNIMPLEMENTED(WARNING) << "genInvoke";
51#else
buzbeee3acd072012-02-25 17:03:10 -080052 DecodedInstruction* dInsn = &mir->dalvikInsn;
53 int callState = 0;
buzbee31a4a6f2012-02-28 15:36:15 -080054 LIR* nullCk;
55 LIR** pNullCk = NULL;
buzbeee3acd072012-02-25 17:03:10 -080056 NextCallInsn nextCallInsn;
57 oatFlushAllRegs(cUnit); /* Everything to home location */
58 // Explicit register usage
59 oatLockCallTemps(cUnit);
60
Logan Chien4dd96f52012-02-29 01:26:58 +080061 OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
buzbee31a4a6f2012-02-28 15:36:15 -080062 *cUnit->dex_file, *cUnit->dex_cache,
63 cUnit->code_item, cUnit->method_idx,
64 cUnit->access_flags);
Logan Chien4dd96f52012-02-29 01:26:58 +080065
buzbeee3acd072012-02-25 17:03:10 -080066 uint32_t dexMethodIdx = dInsn->vB;
67 int vtableIdx;
68 bool skipThis;
69 bool fastPath =
Logan Chien4dd96f52012-02-29 01:26:58 +080070 cUnit->compiler->ComputeInvokeInfo(dexMethodIdx, &mUnit, type,
buzbeee3acd072012-02-25 17:03:10 -080071 vtableIdx)
72 && !SLOW_INVOKE_PATH;
73 if (type == kInterface) {
74 nextCallInsn = fastPath ? nextInterfaceCallInsn
75 : nextInterfaceCallInsnWithAccessCheck;
76 skipThis = false;
77 } else if (type == kDirect) {
78 if (fastPath) {
79 pNullCk = &nullCk;
80 }
81 nextCallInsn = fastPath ? nextSDCallInsn : nextDirectCallInsnSP;
82 skipThis = false;
83 } else if (type == kStatic) {
84 nextCallInsn = fastPath ? nextSDCallInsn : nextStaticCallInsnSP;
85 skipThis = false;
86 } else if (type == kSuper) {
87 nextCallInsn = fastPath ? nextSuperCallInsn : nextSuperCallInsnSP;
88 skipThis = fastPath;
89 } else {
90 DCHECK_EQ(type, kVirtual);
91 nextCallInsn = fastPath ? nextVCallInsn : nextVCallInsnSP;
92 skipThis = fastPath;
93 }
94 if (!isRange) {
95 callState = genDalvikArgsNoRange(cUnit, mir, dInsn, callState, pNullCk,
96 nextCallInsn, dexMethodIdx,
97 vtableIdx, skipThis);
98 } else {
99 callState = genDalvikArgsRange(cUnit, mir, dInsn, callState, pNullCk,
100 nextCallInsn, dexMethodIdx, vtableIdx,
101 skipThis);
102 }
103 // Finish up any of the call sequence not interleaved in arg loading
104 while (callState >= 0) {
105 callState = nextCallInsn(cUnit, mir, callState, dexMethodIdx,
106 vtableIdx);
107 }
108 if (DISPLAY_MISSING_TARGETS) {
109 genShowTarget(cUnit);
110 }
buzbee0398c422012-03-02 15:22:47 -0800111 opReg(cUnit, kOpBlx, rINVOKE_TGT);
buzbeee3acd072012-02-25 17:03:10 -0800112 oatClobberCalleeSave(cUnit);
buzbeea7678db2012-03-05 15:35:46 -0800113#endif
buzbeee3acd072012-02-25 17:03:10 -0800114}
115
116/*
117 * Target-independent code generation. Use only high-level
118 * load/store utilities here, or target-dependent genXX() handlers
119 * when necessary.
120 */
buzbee31a4a6f2012-02-28 15:36:15 -0800121bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
122 BasicBlock* bb, LIR* labelList)
buzbeee3acd072012-02-25 17:03:10 -0800123{
124 bool res = false; // Assume success
125 RegLocation rlSrc[3];
126 RegLocation rlDest = badLoc;
127 RegLocation rlResult = badLoc;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800128 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbeee3acd072012-02-25 17:03:10 -0800129
130 /* Prep Src and Dest locations */
131 int nextSreg = 0;
132 int nextLoc = 0;
133 int attrs = oatDataFlowAttributes[opcode];
134 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
135 if (attrs & DF_UA) {
136 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
137 nextSreg++;
138 } else if (attrs & DF_UA_WIDE) {
139 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
140 nextSreg + 1);
141 nextSreg+= 2;
142 }
143 if (attrs & DF_UB) {
144 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
145 nextSreg++;
146 } else if (attrs & DF_UB_WIDE) {
147 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
148 nextSreg + 1);
149 nextSreg+= 2;
150 }
151 if (attrs & DF_UC) {
152 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
153 } else if (attrs & DF_UC_WIDE) {
154 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
155 nextSreg + 1);
156 }
157 if (attrs & DF_DA) {
158 rlDest = oatGetDest(cUnit, mir, 0);
159 } else if (attrs & DF_DA_WIDE) {
160 rlDest = oatGetDestWide(cUnit, mir, 0, 1);
161 }
162
163 switch(opcode) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800164 case Instruction::NOP:
buzbeee3acd072012-02-25 17:03:10 -0800165 break;
166
Elliott Hughesadb8c672012-03-06 16:49:32 -0800167 case Instruction::MOVE_EXCEPTION:
buzbeea7678db2012-03-05 15:35:46 -0800168#if defined(TARGET_X86)
Elliott Hughesadb8c672012-03-06 16:49:32 -0800169 UNIMPLEMENTED(WARNING) << "Instruction::MOVE_EXCEPTION";
buzbeea7678db2012-03-05 15:35:46 -0800170#else
buzbeee3acd072012-02-25 17:03:10 -0800171 int exOffset;
172 int resetReg;
173 exOffset = Thread::ExceptionOffset().Int32Value();
174 resetReg = oatAllocTemp(cUnit);
175 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
176 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
177 loadConstant(cUnit, resetReg, 0);
178 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
179 storeValue(cUnit, rlDest, rlResult);
buzbeea7678db2012-03-05 15:35:46 -0800180#endif
buzbeee3acd072012-02-25 17:03:10 -0800181 break;
182
Elliott Hughesadb8c672012-03-06 16:49:32 -0800183 case Instruction::RETURN_VOID:
buzbee86a4bce2012-03-06 18:15:00 -0800184 if (!cUnit->attrs & METHOD_IS_LEAF) {
185 genSuspendTest(cUnit, mir);
186 }
buzbeee3acd072012-02-25 17:03:10 -0800187 break;
188
Elliott Hughesadb8c672012-03-06 16:49:32 -0800189 case Instruction::RETURN:
190 case Instruction::RETURN_OBJECT:
buzbee86a4bce2012-03-06 18:15:00 -0800191 if (!cUnit->attrs & METHOD_IS_LEAF) {
192 genSuspendTest(cUnit, mir);
193 }
194 storeValue(cUnit, oatGetReturn(cUnit), rlSrc[0]);
buzbeee3acd072012-02-25 17:03:10 -0800195 break;
196
Elliott Hughesadb8c672012-03-06 16:49:32 -0800197 case Instruction::RETURN_WIDE:
buzbee86a4bce2012-03-06 18:15:00 -0800198 if (!cUnit->attrs & METHOD_IS_LEAF) {
199 genSuspendTest(cUnit, mir);
200 }
201 storeValueWide(cUnit, oatGetReturnWide(cUnit), rlSrc[0]);
buzbeee3acd072012-02-25 17:03:10 -0800202 break;
203
Elliott Hughesadb8c672012-03-06 16:49:32 -0800204 case Instruction::MOVE_RESULT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800205 if (mir->optimizationFlags & MIR_INLINED)
206 break; // Nop - combined w/ previous invoke
buzbee86a4bce2012-03-06 18:15:00 -0800207 storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit));
buzbeee3acd072012-02-25 17:03:10 -0800208 break;
209
Elliott Hughesadb8c672012-03-06 16:49:32 -0800210 case Instruction::MOVE_RESULT:
211 case Instruction::MOVE_RESULT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800212 if (mir->optimizationFlags & MIR_INLINED)
213 break; // Nop - combined w/ previous invoke
buzbee86a4bce2012-03-06 18:15:00 -0800214 storeValue(cUnit, rlDest, oatGetReturn(cUnit));
buzbeee3acd072012-02-25 17:03:10 -0800215 break;
216
Elliott Hughesadb8c672012-03-06 16:49:32 -0800217 case Instruction::MOVE:
218 case Instruction::MOVE_OBJECT:
219 case Instruction::MOVE_16:
220 case Instruction::MOVE_OBJECT_16:
221 case Instruction::MOVE_FROM16:
222 case Instruction::MOVE_OBJECT_FROM16:
buzbeee3acd072012-02-25 17:03:10 -0800223 storeValue(cUnit, rlDest, rlSrc[0]);
224 break;
225
Elliott Hughesadb8c672012-03-06 16:49:32 -0800226 case Instruction::MOVE_WIDE:
227 case Instruction::MOVE_WIDE_16:
228 case Instruction::MOVE_WIDE_FROM16:
buzbeee3acd072012-02-25 17:03:10 -0800229 storeValueWide(cUnit, rlDest, rlSrc[0]);
230 break;
231
Elliott Hughesadb8c672012-03-06 16:49:32 -0800232 case Instruction::CONST:
233 case Instruction::CONST_4:
234 case Instruction::CONST_16:
buzbeee3acd072012-02-25 17:03:10 -0800235 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
236 loadConstantNoClobber(cUnit, rlResult.lowReg, mir->dalvikInsn.vB);
237 storeValue(cUnit, rlDest, rlResult);
238 break;
239
Elliott Hughesadb8c672012-03-06 16:49:32 -0800240 case Instruction::CONST_HIGH16:
buzbeee3acd072012-02-25 17:03:10 -0800241 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
242 loadConstantNoClobber(cUnit, rlResult.lowReg,
243 mir->dalvikInsn.vB << 16);
244 storeValue(cUnit, rlDest, rlResult);
245 break;
246
Elliott Hughesadb8c672012-03-06 16:49:32 -0800247 case Instruction::CONST_WIDE_16:
248 case Instruction::CONST_WIDE_32:
buzbeee3acd072012-02-25 17:03:10 -0800249 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
250 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
251 mir->dalvikInsn.vB,
252 (mir->dalvikInsn.vB & 0x80000000) ? -1 : 0);
253 storeValueWide(cUnit, rlDest, rlResult);
254 break;
255
Elliott Hughesadb8c672012-03-06 16:49:32 -0800256 case Instruction::CONST_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800257 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
258 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
259 mir->dalvikInsn.vB_wide & 0xffffffff,
260 (mir->dalvikInsn.vB_wide >> 32) & 0xffffffff);
261 storeValueWide(cUnit, rlDest, rlResult);
262 break;
263
Elliott Hughesadb8c672012-03-06 16:49:32 -0800264 case Instruction::CONST_WIDE_HIGH16:
buzbeee3acd072012-02-25 17:03:10 -0800265 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
266 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
267 0, mir->dalvikInsn.vB << 16);
268 storeValueWide(cUnit, rlDest, rlResult);
269 break;
270
Elliott Hughesadb8c672012-03-06 16:49:32 -0800271 case Instruction::MONITOR_ENTER:
buzbeee3acd072012-02-25 17:03:10 -0800272 genMonitorEnter(cUnit, mir, rlSrc[0]);
273 break;
274
Elliott Hughesadb8c672012-03-06 16:49:32 -0800275 case Instruction::MONITOR_EXIT:
buzbeee3acd072012-02-25 17:03:10 -0800276 genMonitorExit(cUnit, mir, rlSrc[0]);
277 break;
278
Elliott Hughesadb8c672012-03-06 16:49:32 -0800279 case Instruction::CHECK_CAST:
buzbeee3acd072012-02-25 17:03:10 -0800280 genCheckCast(cUnit, mir, rlSrc[0]);
281 break;
282
Elliott Hughesadb8c672012-03-06 16:49:32 -0800283 case Instruction::INSTANCE_OF:
buzbeee3acd072012-02-25 17:03:10 -0800284 genInstanceof(cUnit, mir, rlDest, rlSrc[0]);
285 break;
286
Elliott Hughesadb8c672012-03-06 16:49:32 -0800287 case Instruction::NEW_INSTANCE:
buzbeee3acd072012-02-25 17:03:10 -0800288 genNewInstance(cUnit, mir, rlDest);
289 break;
290
Elliott Hughesadb8c672012-03-06 16:49:32 -0800291 case Instruction::THROW:
buzbeee3acd072012-02-25 17:03:10 -0800292 genThrow(cUnit, mir, rlSrc[0]);
293 break;
294
Elliott Hughesadb8c672012-03-06 16:49:32 -0800295 case Instruction::THROW_VERIFICATION_ERROR:
buzbeee3acd072012-02-25 17:03:10 -0800296 genThrowVerificationError(cUnit, mir);
297 break;
298
Elliott Hughesadb8c672012-03-06 16:49:32 -0800299 case Instruction::ARRAY_LENGTH:
buzbeee3acd072012-02-25 17:03:10 -0800300 int lenOffset;
301 lenOffset = Array::LengthOffset().Int32Value();
302 rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
303 genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, mir);
304 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
305 loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset,
306 rlResult.lowReg);
307 storeValue(cUnit, rlDest, rlResult);
308 break;
309
Elliott Hughesadb8c672012-03-06 16:49:32 -0800310 case Instruction::CONST_STRING:
311 case Instruction::CONST_STRING_JUMBO:
buzbeee3acd072012-02-25 17:03:10 -0800312 genConstString(cUnit, mir, rlDest, rlSrc[0]);
313 break;
314
Elliott Hughesadb8c672012-03-06 16:49:32 -0800315 case Instruction::CONST_CLASS:
buzbeee3acd072012-02-25 17:03:10 -0800316 genConstClass(cUnit, mir, rlDest, rlSrc[0]);
317 break;
318
Elliott Hughesadb8c672012-03-06 16:49:32 -0800319 case Instruction::FILL_ARRAY_DATA:
buzbeee3acd072012-02-25 17:03:10 -0800320 genFillArrayData(cUnit, mir, rlSrc[0]);
321 break;
322
Elliott Hughesadb8c672012-03-06 16:49:32 -0800323 case Instruction::FILLED_NEW_ARRAY:
buzbeee3acd072012-02-25 17:03:10 -0800324 genFilledNewArray(cUnit, mir, false /* not range */);
325 break;
326
Elliott Hughesadb8c672012-03-06 16:49:32 -0800327 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800328 genFilledNewArray(cUnit, mir, true /* range */);
329 break;
330
Elliott Hughesadb8c672012-03-06 16:49:32 -0800331 case Instruction::NEW_ARRAY:
buzbeee3acd072012-02-25 17:03:10 -0800332 genNewArray(cUnit, mir, rlDest, rlSrc[0]);
333 break;
334
Elliott Hughesadb8c672012-03-06 16:49:32 -0800335 case Instruction::GOTO:
336 case Instruction::GOTO_16:
337 case Instruction::GOTO_32:
buzbeee3acd072012-02-25 17:03:10 -0800338 if (bb->taken->startOffset <= mir->offset) {
339 genSuspendTest(cUnit, mir);
340 }
buzbee82488f52012-03-02 08:20:26 -0800341 opUnconditionalBranch(cUnit, &labelList[bb->taken->id]);
buzbeee3acd072012-02-25 17:03:10 -0800342 break;
343
Elliott Hughesadb8c672012-03-06 16:49:32 -0800344 case Instruction::PACKED_SWITCH:
buzbeee3acd072012-02-25 17:03:10 -0800345 genPackedSwitch(cUnit, mir, rlSrc[0]);
346 break;
347
Elliott Hughesadb8c672012-03-06 16:49:32 -0800348 case Instruction::SPARSE_SWITCH:
buzbeee3acd072012-02-25 17:03:10 -0800349 genSparseSwitch(cUnit, mir, rlSrc[0]);
350 break;
351
Elliott Hughesadb8c672012-03-06 16:49:32 -0800352 case Instruction::CMPL_FLOAT:
353 case Instruction::CMPG_FLOAT:
354 case Instruction::CMPL_DOUBLE:
355 case Instruction::CMPG_DOUBLE:
buzbeee3acd072012-02-25 17:03:10 -0800356 res = genCmpFP(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
357 break;
358
Elliott Hughesadb8c672012-03-06 16:49:32 -0800359 case Instruction::CMP_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800360 genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
361 break;
362
Elliott Hughesadb8c672012-03-06 16:49:32 -0800363 case Instruction::IF_EQ:
364 case Instruction::IF_NE:
365 case Instruction::IF_LT:
366 case Instruction::IF_GE:
367 case Instruction::IF_GT:
368 case Instruction::IF_LE: {
buzbeee3acd072012-02-25 17:03:10 -0800369 bool backwardBranch;
370 backwardBranch = (bb->taken->startOffset <= mir->offset);
371 if (backwardBranch) {
372 genSuspendTest(cUnit, mir);
373 }
374 genCompareAndBranch(cUnit, bb, mir, rlSrc[0], rlSrc[1], labelList);
375 break;
376 }
377
Elliott Hughesadb8c672012-03-06 16:49:32 -0800378 case Instruction::IF_EQZ:
379 case Instruction::IF_NEZ:
380 case Instruction::IF_LTZ:
381 case Instruction::IF_GEZ:
382 case Instruction::IF_GTZ:
383 case Instruction::IF_LEZ: {
buzbeee3acd072012-02-25 17:03:10 -0800384 bool backwardBranch;
385 backwardBranch = (bb->taken->startOffset <= mir->offset);
386 if (backwardBranch) {
387 genSuspendTest(cUnit, mir);
388 }
389 genCompareZeroAndBranch(cUnit, bb, mir, rlSrc[0], labelList);
390 break;
391 }
392
Elliott Hughesadb8c672012-03-06 16:49:32 -0800393 case Instruction::AGET_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800394 genArrayGet(cUnit, mir, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
395 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800396 case Instruction::AGET:
397 case Instruction::AGET_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800398 genArrayGet(cUnit, mir, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
399 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800400 case Instruction::AGET_BOOLEAN:
buzbeee3acd072012-02-25 17:03:10 -0800401 genArrayGet(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1],
402 rlDest, 0);
403 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800404 case Instruction::AGET_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800405 genArrayGet(cUnit, mir, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
406 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800407 case Instruction::AGET_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800408 genArrayGet(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1],
409 rlDest, 1);
410 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800411 case Instruction::AGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800412 genArrayGet(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
413 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800414 case Instruction::APUT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800415 genArrayPut(cUnit, mir, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
416 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800417 case Instruction::APUT:
buzbeee3acd072012-02-25 17:03:10 -0800418 genArrayPut(cUnit, mir, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
419 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800420 case Instruction::APUT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800421 genArrayObjPut(cUnit, mir, rlSrc[1], rlSrc[2], rlSrc[0], 2);
422 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800423 case Instruction::APUT_SHORT:
424 case Instruction::APUT_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800425 genArrayPut(cUnit, mir, kUnsignedHalf, rlSrc[1], rlSrc[2],
426 rlSrc[0], 1);
427 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800428 case Instruction::APUT_BYTE:
429 case Instruction::APUT_BOOLEAN:
buzbeee3acd072012-02-25 17:03:10 -0800430 genArrayPut(cUnit, mir, kUnsignedByte, rlSrc[1], rlSrc[2],
431 rlSrc[0], 0);
432 break;
433
Elliott Hughesadb8c672012-03-06 16:49:32 -0800434 case Instruction::IGET_OBJECT:
435 //case Instruction::IGET_OBJECT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800436 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, true);
437 break;
438
Elliott Hughesadb8c672012-03-06 16:49:32 -0800439 case Instruction::IGET_WIDE:
440 //case Instruction::IGET_WIDE_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800441 genIGet(cUnit, mir, kLong, rlDest, rlSrc[0], true, false);
442 break;
443
Elliott Hughesadb8c672012-03-06 16:49:32 -0800444 case Instruction::IGET:
445 //case Instruction::IGET_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800446 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, false);
447 break;
448
Elliott Hughesadb8c672012-03-06 16:49:32 -0800449 case Instruction::IGET_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800450 genIGet(cUnit, mir, kUnsignedHalf, rlDest, rlSrc[0], false, false);
451 break;
452
Elliott Hughesadb8c672012-03-06 16:49:32 -0800453 case Instruction::IGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800454 genIGet(cUnit, mir, kSignedHalf, rlDest, rlSrc[0], false, false);
455 break;
456
Elliott Hughesadb8c672012-03-06 16:49:32 -0800457 case Instruction::IGET_BOOLEAN:
458 case Instruction::IGET_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800459 genIGet(cUnit, mir, kUnsignedByte, rlDest, rlSrc[0], false, false);
460 break;
461
Elliott Hughesadb8c672012-03-06 16:49:32 -0800462 case Instruction::IPUT_WIDE:
463 //case Instruction::IPUT_WIDE_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800464 genIPut(cUnit, mir, kLong, rlSrc[0], rlSrc[1], true, false);
465 break;
466
Elliott Hughesadb8c672012-03-06 16:49:32 -0800467 case Instruction::IPUT_OBJECT:
468 //case Instruction::IPUT_OBJECT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800469 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, true);
470 break;
471
Elliott Hughesadb8c672012-03-06 16:49:32 -0800472 case Instruction::IPUT:
473 //case Instruction::IPUT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800474 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, false);
475 break;
476
Elliott Hughesadb8c672012-03-06 16:49:32 -0800477 case Instruction::IPUT_BOOLEAN:
478 case Instruction::IPUT_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800479 genIPut(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
480 break;
481
Elliott Hughesadb8c672012-03-06 16:49:32 -0800482 case Instruction::IPUT_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800483 genIPut(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
484 break;
485
Elliott Hughesadb8c672012-03-06 16:49:32 -0800486 case Instruction::IPUT_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800487 genIPut(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
488 break;
489
Elliott Hughesadb8c672012-03-06 16:49:32 -0800490 case Instruction::SGET_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800491 genSget(cUnit, mir, rlDest, false, true);
492 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800493 case Instruction::SGET:
494 case Instruction::SGET_BOOLEAN:
495 case Instruction::SGET_BYTE:
496 case Instruction::SGET_CHAR:
497 case Instruction::SGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800498 genSget(cUnit, mir, rlDest, false, false);
499 break;
500
Elliott Hughesadb8c672012-03-06 16:49:32 -0800501 case Instruction::SGET_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800502 genSget(cUnit, mir, rlDest, true, false);
503 break;
504
Elliott Hughesadb8c672012-03-06 16:49:32 -0800505 case Instruction::SPUT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800506 genSput(cUnit, mir, rlSrc[0], false, true);
507 break;
508
Elliott Hughesadb8c672012-03-06 16:49:32 -0800509 case Instruction::SPUT:
510 case Instruction::SPUT_BOOLEAN:
511 case Instruction::SPUT_BYTE:
512 case Instruction::SPUT_CHAR:
513 case Instruction::SPUT_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800514 genSput(cUnit, mir, rlSrc[0], false, false);
515 break;
516
Elliott Hughesadb8c672012-03-06 16:49:32 -0800517 case Instruction::SPUT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800518 genSput(cUnit, mir, rlSrc[0], true, false);
519 break;
520
Elliott Hughesadb8c672012-03-06 16:49:32 -0800521 case Instruction::INVOKE_STATIC_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800522 genInvoke(cUnit, mir, kStatic, true /*range*/);
523 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800524 case Instruction::INVOKE_STATIC:
buzbeee3acd072012-02-25 17:03:10 -0800525 genInvoke(cUnit, mir, kStatic, false /*range*/);
526 break;
527
Elliott Hughesadb8c672012-03-06 16:49:32 -0800528 case Instruction::INVOKE_DIRECT:
buzbeee3acd072012-02-25 17:03:10 -0800529 genInvoke(cUnit, mir, kDirect, false /*range*/);
530 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800531 case Instruction::INVOKE_DIRECT_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800532 genInvoke(cUnit, mir, kDirect, true /*range*/);
533 break;
534
Elliott Hughesadb8c672012-03-06 16:49:32 -0800535 case Instruction::INVOKE_VIRTUAL:
buzbeee3acd072012-02-25 17:03:10 -0800536 genInvoke(cUnit, mir, kVirtual, false /*range*/);
537 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800538 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800539 genInvoke(cUnit, mir, kVirtual, true /*range*/);
540 break;
541
Elliott Hughesadb8c672012-03-06 16:49:32 -0800542 case Instruction::INVOKE_SUPER:
buzbeee3acd072012-02-25 17:03:10 -0800543 genInvoke(cUnit, mir, kSuper, false /*range*/);
544 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800545 case Instruction::INVOKE_SUPER_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800546 genInvoke(cUnit, mir, kSuper, true /*range*/);
547 break;
548
Elliott Hughesadb8c672012-03-06 16:49:32 -0800549 case Instruction::INVOKE_INTERFACE:
buzbeee3acd072012-02-25 17:03:10 -0800550 genInvoke(cUnit, mir, kInterface, false /*range*/);
551 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800552 case Instruction::INVOKE_INTERFACE_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800553 genInvoke(cUnit, mir, kInterface, true /*range*/);
554 break;
555
Elliott Hughesadb8c672012-03-06 16:49:32 -0800556 case Instruction::NEG_INT:
557 case Instruction::NOT_INT:
buzbeee3acd072012-02-25 17:03:10 -0800558 res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
559 break;
560
Elliott Hughesadb8c672012-03-06 16:49:32 -0800561 case Instruction::NEG_LONG:
562 case Instruction::NOT_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800563 res = genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
564 break;
565
Elliott Hughesadb8c672012-03-06 16:49:32 -0800566 case Instruction::NEG_FLOAT:
buzbeee3acd072012-02-25 17:03:10 -0800567 res = genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
568 break;
569
Elliott Hughesadb8c672012-03-06 16:49:32 -0800570 case Instruction::NEG_DOUBLE:
buzbeee3acd072012-02-25 17:03:10 -0800571 res = genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
572 break;
573
Elliott Hughesadb8c672012-03-06 16:49:32 -0800574 case Instruction::INT_TO_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800575 genIntToLong(cUnit, mir, rlDest, rlSrc[0]);
576 break;
577
Elliott Hughesadb8c672012-03-06 16:49:32 -0800578 case Instruction::LONG_TO_INT:
buzbeee3acd072012-02-25 17:03:10 -0800579 rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
580 rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
581 storeValue(cUnit, rlDest, rlSrc[0]);
582 break;
583
Elliott Hughesadb8c672012-03-06 16:49:32 -0800584 case Instruction::INT_TO_BYTE:
585 case Instruction::INT_TO_SHORT:
586 case Instruction::INT_TO_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800587 genIntNarrowing(cUnit, mir, rlDest, rlSrc[0]);
588 break;
589
Elliott Hughesadb8c672012-03-06 16:49:32 -0800590 case Instruction::INT_TO_FLOAT:
591 case Instruction::INT_TO_DOUBLE:
592 case Instruction::LONG_TO_FLOAT:
593 case Instruction::LONG_TO_DOUBLE:
594 case Instruction::FLOAT_TO_INT:
595 case Instruction::FLOAT_TO_LONG:
596 case Instruction::FLOAT_TO_DOUBLE:
597 case Instruction::DOUBLE_TO_INT:
598 case Instruction::DOUBLE_TO_LONG:
599 case Instruction::DOUBLE_TO_FLOAT:
buzbeee3acd072012-02-25 17:03:10 -0800600 genConversion(cUnit, mir);
601 break;
602
Elliott Hughesadb8c672012-03-06 16:49:32 -0800603 case Instruction::ADD_INT:
604 case Instruction::SUB_INT:
605 case Instruction::MUL_INT:
606 case Instruction::DIV_INT:
607 case Instruction::REM_INT:
608 case Instruction::AND_INT:
609 case Instruction::OR_INT:
610 case Instruction::XOR_INT:
611 case Instruction::SHL_INT:
612 case Instruction::SHR_INT:
613 case Instruction::USHR_INT:
614 case Instruction::ADD_INT_2ADDR:
615 case Instruction::SUB_INT_2ADDR:
616 case Instruction::MUL_INT_2ADDR:
617 case Instruction::DIV_INT_2ADDR:
618 case Instruction::REM_INT_2ADDR:
619 case Instruction::AND_INT_2ADDR:
620 case Instruction::OR_INT_2ADDR:
621 case Instruction::XOR_INT_2ADDR:
622 case Instruction::SHL_INT_2ADDR:
623 case Instruction::SHR_INT_2ADDR:
624 case Instruction::USHR_INT_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800625 genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
626 break;
627
Elliott Hughesadb8c672012-03-06 16:49:32 -0800628 case Instruction::ADD_LONG:
629 case Instruction::SUB_LONG:
630 case Instruction::MUL_LONG:
631 case Instruction::DIV_LONG:
632 case Instruction::REM_LONG:
633 case Instruction::AND_LONG:
634 case Instruction::OR_LONG:
635 case Instruction::XOR_LONG:
636 case Instruction::ADD_LONG_2ADDR:
637 case Instruction::SUB_LONG_2ADDR:
638 case Instruction::MUL_LONG_2ADDR:
639 case Instruction::DIV_LONG_2ADDR:
640 case Instruction::REM_LONG_2ADDR:
641 case Instruction::AND_LONG_2ADDR:
642 case Instruction::OR_LONG_2ADDR:
643 case Instruction::XOR_LONG_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800644 genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
645 break;
646
Elliott Hughesadb8c672012-03-06 16:49:32 -0800647 case Instruction::SHL_LONG:
648 case Instruction::SHR_LONG:
649 case Instruction::USHR_LONG:
650 case Instruction::SHL_LONG_2ADDR:
651 case Instruction::SHR_LONG_2ADDR:
652 case Instruction::USHR_LONG_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800653 genShiftOpLong(cUnit,mir, rlDest, rlSrc[0], rlSrc[1]);
654 break;
655
Elliott Hughesadb8c672012-03-06 16:49:32 -0800656 case Instruction::ADD_FLOAT:
657 case Instruction::SUB_FLOAT:
658 case Instruction::MUL_FLOAT:
659 case Instruction::DIV_FLOAT:
660 case Instruction::REM_FLOAT:
661 case Instruction::ADD_FLOAT_2ADDR:
662 case Instruction::SUB_FLOAT_2ADDR:
663 case Instruction::MUL_FLOAT_2ADDR:
664 case Instruction::DIV_FLOAT_2ADDR:
665 case Instruction::REM_FLOAT_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800666 genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
667 break;
668
Elliott Hughesadb8c672012-03-06 16:49:32 -0800669 case Instruction::ADD_DOUBLE:
670 case Instruction::SUB_DOUBLE:
671 case Instruction::MUL_DOUBLE:
672 case Instruction::DIV_DOUBLE:
673 case Instruction::REM_DOUBLE:
674 case Instruction::ADD_DOUBLE_2ADDR:
675 case Instruction::SUB_DOUBLE_2ADDR:
676 case Instruction::MUL_DOUBLE_2ADDR:
677 case Instruction::DIV_DOUBLE_2ADDR:
678 case Instruction::REM_DOUBLE_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800679 genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
680 break;
681
Elliott Hughesadb8c672012-03-06 16:49:32 -0800682 case Instruction::RSUB_INT:
683 case Instruction::ADD_INT_LIT16:
684 case Instruction::MUL_INT_LIT16:
685 case Instruction::DIV_INT_LIT16:
686 case Instruction::REM_INT_LIT16:
687 case Instruction::AND_INT_LIT16:
688 case Instruction::OR_INT_LIT16:
689 case Instruction::XOR_INT_LIT16:
690 case Instruction::ADD_INT_LIT8:
691 case Instruction::RSUB_INT_LIT8:
692 case Instruction::MUL_INT_LIT8:
693 case Instruction::DIV_INT_LIT8:
694 case Instruction::REM_INT_LIT8:
695 case Instruction::AND_INT_LIT8:
696 case Instruction::OR_INT_LIT8:
697 case Instruction::XOR_INT_LIT8:
698 case Instruction::SHL_INT_LIT8:
699 case Instruction::SHR_INT_LIT8:
700 case Instruction::USHR_INT_LIT8:
buzbeee3acd072012-02-25 17:03:10 -0800701 genArithOpIntLit(cUnit, mir, rlDest, rlSrc[0], mir->dalvikInsn.vC);
702 break;
703
704 default:
705 res = true;
706 }
707 return res;
708}
709
buzbee31a4a6f2012-02-28 15:36:15 -0800710const char* extendedMIROpNames[kMirOpLast - kMirOpFirst] = {
buzbeee3acd072012-02-25 17:03:10 -0800711 "kMirOpPhi",
712 "kMirOpNullNRangeUpCheck",
713 "kMirOpNullNRangeDownCheck",
714 "kMirOpLowerBound",
715 "kMirOpPunt",
716 "kMirOpCheckInlinePrediction",
717};
718
719/* Extended MIR instructions like PHI */
buzbee31a4a6f2012-02-28 15:36:15 -0800720void handleExtendedMethodMIR(CompilationUnit* cUnit, MIR* mir)
buzbeee3acd072012-02-25 17:03:10 -0800721{
722 int opOffset = mir->dalvikInsn.opcode - kMirOpFirst;
723 char* msg = NULL;
724 if (cUnit->printMe) {
725 msg = (char*)oatNew(cUnit, strlen(extendedMIROpNames[opOffset]) + 1,
726 false, kAllocDebugInfo);
727 strcpy(msg, extendedMIROpNames[opOffset]);
728 }
buzbee31a4a6f2012-02-28 15:36:15 -0800729 LIR* op = newLIR1(cUnit, kPseudoExtended, (int) msg);
buzbeee3acd072012-02-25 17:03:10 -0800730
731 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
732 case kMirOpPhi: {
733 char* ssaString = NULL;
734 if (cUnit->printMe) {
735 ssaString = oatGetSSAString(cUnit, mir->ssaRep);
736 }
737 op->flags.isNop = true;
buzbee31a4a6f2012-02-28 15:36:15 -0800738 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
buzbeee3acd072012-02-25 17:03:10 -0800739 break;
740 }
741 default:
742 break;
743 }
744}
745
746/* Handle the content in each basic block */
buzbee31a4a6f2012-02-28 15:36:15 -0800747bool methodBlockCodeGen(CompilationUnit* cUnit, BasicBlock* bb)
buzbeee3acd072012-02-25 17:03:10 -0800748{
749 MIR* mir;
buzbee31a4a6f2012-02-28 15:36:15 -0800750 LIR* labelList = (LIR*) cUnit->blockLabelList;
buzbeee3acd072012-02-25 17:03:10 -0800751 int blockId = bb->id;
752
753 cUnit->curBlock = bb;
754 labelList[blockId].operands[0] = bb->startOffset;
755
756 /* Insert the block label */
buzbee31a4a6f2012-02-28 15:36:15 -0800757 labelList[blockId].opcode = kPseudoNormalBlockLabel;
buzbeee3acd072012-02-25 17:03:10 -0800758 oatAppendLIR(cUnit, (LIR*) &labelList[blockId]);
759
760 /* Reset local optimization data on block boundaries */
761 oatResetRegPool(cUnit);
762 oatClobberAllRegs(cUnit);
763 oatResetDefTracking(cUnit);
764
buzbee31a4a6f2012-02-28 15:36:15 -0800765 LIR* headLIR = NULL;
buzbeee3acd072012-02-25 17:03:10 -0800766
767 if (bb->blockType == kEntryBlock) {
768 genEntrySequence(cUnit, bb);
769 } else if (bb->blockType == kExitBlock) {
770 genExitSequence(cUnit, bb);
771 }
772
773 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
774
775 oatResetRegPool(cUnit);
776 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
777 oatClobberAllRegs(cUnit);
778 }
779
780 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
781 oatResetDefTracking(cUnit);
782 }
783
784 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
785 handleExtendedMethodMIR(cUnit, mir);
786 continue;
787 }
788
789 cUnit->currentDalvikOffset = mir->offset;
790
Elliott Hughesadb8c672012-03-06 16:49:32 -0800791 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
792 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
buzbeee3acd072012-02-25 17:03:10 -0800793
buzbee31a4a6f2012-02-28 15:36:15 -0800794 LIR* boundaryLIR;
buzbeee3acd072012-02-25 17:03:10 -0800795
796 /* Mark the beginning of a Dalvik instruction for line tracking */
797 char* instStr = cUnit->printMe ?
Elliott Hughesadb8c672012-03-06 16:49:32 -0800798 oatGetDalvikDisassembly(cUnit, mir->dalvikInsn, "") : NULL;
buzbee31a4a6f2012-02-28 15:36:15 -0800799 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
buzbeee3acd072012-02-25 17:03:10 -0800800 (intptr_t) instStr);
801 cUnit->boundaryMap.insert(std::make_pair(mir->offset,
802 (LIR*)boundaryLIR));
803 /* Remember the first LIR for this block */
804 if (headLIR == NULL) {
805 headLIR = boundaryLIR;
806 /* Set the first boundaryLIR as a scheduling barrier */
807 headLIR->defMask = ENCODE_ALL;
808 }
809
810 /* If we're compiling for the debugger, generate an update callout */
811 if (cUnit->genDebugger) {
812 genDebuggerUpdate(cUnit, mir->offset);
813 }
814
815 /* Don't generate the SSA annotation unless verbose mode is on */
816 if (cUnit->printMe && mir->ssaRep) {
817 char* ssaString = oatGetSSAString(cUnit, mir->ssaRep);
buzbee31a4a6f2012-02-28 15:36:15 -0800818 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
buzbeee3acd072012-02-25 17:03:10 -0800819 }
820
821 bool notHandled = compileDalvikInstruction(cUnit, mir, bb, labelList);
buzbeee3acd072012-02-25 17:03:10 -0800822 if (notHandled) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800823 LOG(FATAL) << StringPrintf("%#06x: Opcode %#x (%s) / Fmt %d not handled",
824 mir->offset, dalvikOpcode, Instruction::Name(dalvikOpcode), dalvikFormat);
825
buzbeee3acd072012-02-25 17:03:10 -0800826 }
827 }
828
829 if (headLIR) {
830 /*
831 * Eliminate redundant loads/stores and delay stores into later
832 * slots
833 */
834 oatApplyLocalOptimizations(cUnit, (LIR*) headLIR,
835 cUnit->lastLIRInsn);
836
837 /*
838 * Generate an unconditional branch to the fallthrough block.
839 */
840 if (bb->fallThrough) {
buzbee82488f52012-03-02 08:20:26 -0800841 opUnconditionalBranch(cUnit,
842 &labelList[bb->fallThrough->id]);
buzbeee3acd072012-02-25 17:03:10 -0800843 }
844 }
845 return false;
846}
847
848void oatMethodMIR2LIR(CompilationUnit* cUnit)
849{
850 /* Used to hold the labels of each block */
851 cUnit->blockLabelList =
buzbee31a4a6f2012-02-28 15:36:15 -0800852 (void *) oatNew(cUnit, sizeof(LIR) * cUnit->numBlocks, true,
buzbeee3acd072012-02-25 17:03:10 -0800853 kAllocLIR);
854
855 oatDataFlowAnalysisDispatcher(cUnit, methodBlockCodeGen,
856 kPreOrderDFSTraversal, false /* Iterative */);
857 handleSuspendLaunchpads(cUnit);
858
859 handleThrowLaunchpads(cUnit);
860
buzbee86a4bce2012-03-06 18:15:00 -0800861 if (!(cUnit->disableOpt & (1 << kSafeOptimizations))) {
862 removeRedundantBranches(cUnit);
863 }
buzbeee3acd072012-02-25 17:03:10 -0800864}
865
866/* Needed by the ld/st optmizatons */
buzbee31a4a6f2012-02-28 15:36:15 -0800867LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
buzbeee3acd072012-02-25 17:03:10 -0800868{
buzbee82488f52012-03-02 08:20:26 -0800869 return opRegCopyNoInsert(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -0800870}
871
872/* Needed by the register allocator */
873void oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
874{
buzbee82488f52012-03-02 08:20:26 -0800875 opRegCopy(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -0800876}
877
878/* Needed by the register allocator */
879void oatRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
880 int srcLo, int srcHi)
881{
buzbee82488f52012-03-02 08:20:26 -0800882 opRegCopyWide(cUnit, destLo, destHi, srcLo, srcHi);
buzbeee3acd072012-02-25 17:03:10 -0800883}
884
885void oatFlushRegImpl(CompilationUnit* cUnit, int rBase,
886 int displacement, int rSrc, OpSize size)
887{
888 storeBaseDisp(cUnit, rBase, displacement, rSrc, size);
889}
890
891void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase,
892 int displacement, int rSrcLo, int rSrcHi)
893{
894 storeBaseDispWide(cUnit, rBase, displacement, rSrcLo, rSrcHi);
895}
896
897} // namespace art