blob: 6b3283e13fc9a86af45f6370442830f455d40ef6 [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);
Elliott Hughesb3cd1222012-03-09 16:00:38 -080043 if (cUnit->instructionSet == kMips) {
44 oatMarkInUse(cUnit, res.lowReg);
45 } else {
46 oatLockTemp(cUnit, res.lowReg);
47 }
buzbeee3acd072012-02-25 17:03:10 -080048 return res;
49}
50
buzbee31a4a6f2012-02-28 15:36:15 -080051void genInvoke(CompilationUnit* cUnit, MIR* mir, InvokeType type, bool isRange)
buzbeee3acd072012-02-25 17:03:10 -080052{
buzbeea7678db2012-03-05 15:35:46 -080053#if defined(TARGET_X86)
54 UNIMPLEMENTED(WARNING) << "genInvoke";
55#else
buzbeee3acd072012-02-25 17:03:10 -080056 DecodedInstruction* dInsn = &mir->dalvikInsn;
57 int callState = 0;
buzbee31a4a6f2012-02-28 15:36:15 -080058 LIR* nullCk;
59 LIR** pNullCk = NULL;
buzbeee3acd072012-02-25 17:03:10 -080060 NextCallInsn nextCallInsn;
61 oatFlushAllRegs(cUnit); /* Everything to home location */
62 // Explicit register usage
63 oatLockCallTemps(cUnit);
64
Logan Chien4dd96f52012-02-29 01:26:58 +080065 OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
buzbee31a4a6f2012-02-28 15:36:15 -080066 *cUnit->dex_file, *cUnit->dex_cache,
67 cUnit->code_item, cUnit->method_idx,
68 cUnit->access_flags);
Logan Chien4dd96f52012-02-29 01:26:58 +080069
buzbeee3acd072012-02-25 17:03:10 -080070 uint32_t dexMethodIdx = dInsn->vB;
71 int vtableIdx;
72 bool skipThis;
73 bool fastPath =
Logan Chien4dd96f52012-02-29 01:26:58 +080074 cUnit->compiler->ComputeInvokeInfo(dexMethodIdx, &mUnit, type,
buzbeee3acd072012-02-25 17:03:10 -080075 vtableIdx)
76 && !SLOW_INVOKE_PATH;
77 if (type == kInterface) {
78 nextCallInsn = fastPath ? nextInterfaceCallInsn
79 : nextInterfaceCallInsnWithAccessCheck;
80 skipThis = false;
81 } else if (type == kDirect) {
82 if (fastPath) {
83 pNullCk = &nullCk;
84 }
85 nextCallInsn = fastPath ? nextSDCallInsn : nextDirectCallInsnSP;
86 skipThis = false;
87 } else if (type == kStatic) {
88 nextCallInsn = fastPath ? nextSDCallInsn : nextStaticCallInsnSP;
89 skipThis = false;
90 } else if (type == kSuper) {
91 nextCallInsn = fastPath ? nextSuperCallInsn : nextSuperCallInsnSP;
92 skipThis = fastPath;
93 } else {
94 DCHECK_EQ(type, kVirtual);
95 nextCallInsn = fastPath ? nextVCallInsn : nextVCallInsnSP;
96 skipThis = fastPath;
97 }
98 if (!isRange) {
99 callState = genDalvikArgsNoRange(cUnit, mir, dInsn, callState, pNullCk,
100 nextCallInsn, dexMethodIdx,
101 vtableIdx, skipThis);
102 } else {
103 callState = genDalvikArgsRange(cUnit, mir, dInsn, callState, pNullCk,
104 nextCallInsn, dexMethodIdx, vtableIdx,
105 skipThis);
106 }
107 // Finish up any of the call sequence not interleaved in arg loading
108 while (callState >= 0) {
109 callState = nextCallInsn(cUnit, mir, callState, dexMethodIdx,
110 vtableIdx);
111 }
112 if (DISPLAY_MISSING_TARGETS) {
113 genShowTarget(cUnit);
114 }
buzbee0398c422012-03-02 15:22:47 -0800115 opReg(cUnit, kOpBlx, rINVOKE_TGT);
buzbeee3acd072012-02-25 17:03:10 -0800116 oatClobberCalleeSave(cUnit);
buzbeea7678db2012-03-05 15:35:46 -0800117#endif
buzbeee3acd072012-02-25 17:03:10 -0800118}
119
120/*
121 * Target-independent code generation. Use only high-level
122 * load/store utilities here, or target-dependent genXX() handlers
123 * when necessary.
124 */
buzbee31a4a6f2012-02-28 15:36:15 -0800125bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
126 BasicBlock* bb, LIR* labelList)
buzbeee3acd072012-02-25 17:03:10 -0800127{
128 bool res = false; // Assume success
129 RegLocation rlSrc[3];
130 RegLocation rlDest = badLoc;
131 RegLocation rlResult = badLoc;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800132 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbeee3acd072012-02-25 17:03:10 -0800133
134 /* Prep Src and Dest locations */
135 int nextSreg = 0;
136 int nextLoc = 0;
137 int attrs = oatDataFlowAttributes[opcode];
138 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
139 if (attrs & DF_UA) {
140 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
141 nextSreg++;
142 } else if (attrs & DF_UA_WIDE) {
143 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
144 nextSreg + 1);
145 nextSreg+= 2;
146 }
147 if (attrs & DF_UB) {
148 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
149 nextSreg++;
150 } else if (attrs & DF_UB_WIDE) {
151 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
152 nextSreg + 1);
153 nextSreg+= 2;
154 }
155 if (attrs & DF_UC) {
156 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
157 } else if (attrs & DF_UC_WIDE) {
158 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
159 nextSreg + 1);
160 }
161 if (attrs & DF_DA) {
162 rlDest = oatGetDest(cUnit, mir, 0);
163 } else if (attrs & DF_DA_WIDE) {
164 rlDest = oatGetDestWide(cUnit, mir, 0, 1);
165 }
166
167 switch(opcode) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800168 case Instruction::NOP:
buzbeee3acd072012-02-25 17:03:10 -0800169 break;
170
Elliott Hughesadb8c672012-03-06 16:49:32 -0800171 case Instruction::MOVE_EXCEPTION:
buzbeea7678db2012-03-05 15:35:46 -0800172#if defined(TARGET_X86)
Elliott Hughesadb8c672012-03-06 16:49:32 -0800173 UNIMPLEMENTED(WARNING) << "Instruction::MOVE_EXCEPTION";
buzbeea7678db2012-03-05 15:35:46 -0800174#else
buzbeee3acd072012-02-25 17:03:10 -0800175 int exOffset;
176 int resetReg;
177 exOffset = Thread::ExceptionOffset().Int32Value();
178 resetReg = oatAllocTemp(cUnit);
179 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
180 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
181 loadConstant(cUnit, resetReg, 0);
182 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
183 storeValue(cUnit, rlDest, rlResult);
buzbeea7678db2012-03-05 15:35:46 -0800184#endif
buzbeee3acd072012-02-25 17:03:10 -0800185 break;
186
Elliott Hughesadb8c672012-03-06 16:49:32 -0800187 case Instruction::RETURN_VOID:
buzbee86a4bce2012-03-06 18:15:00 -0800188 if (!cUnit->attrs & METHOD_IS_LEAF) {
189 genSuspendTest(cUnit, mir);
190 }
buzbeee3acd072012-02-25 17:03:10 -0800191 break;
192
Elliott Hughesadb8c672012-03-06 16:49:32 -0800193 case Instruction::RETURN:
194 case Instruction::RETURN_OBJECT:
buzbee86a4bce2012-03-06 18:15:00 -0800195 if (!cUnit->attrs & METHOD_IS_LEAF) {
196 genSuspendTest(cUnit, mir);
197 }
198 storeValue(cUnit, oatGetReturn(cUnit), rlSrc[0]);
buzbeee3acd072012-02-25 17:03:10 -0800199 break;
200
Elliott Hughesadb8c672012-03-06 16:49:32 -0800201 case Instruction::RETURN_WIDE:
buzbee86a4bce2012-03-06 18:15:00 -0800202 if (!cUnit->attrs & METHOD_IS_LEAF) {
203 genSuspendTest(cUnit, mir);
204 }
205 storeValueWide(cUnit, oatGetReturnWide(cUnit), rlSrc[0]);
buzbeee3acd072012-02-25 17:03:10 -0800206 break;
207
Elliott Hughesadb8c672012-03-06 16:49:32 -0800208 case Instruction::MOVE_RESULT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800209 if (mir->optimizationFlags & MIR_INLINED)
210 break; // Nop - combined w/ previous invoke
buzbee86a4bce2012-03-06 18:15:00 -0800211 storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit));
buzbeee3acd072012-02-25 17:03:10 -0800212 break;
213
Elliott Hughesadb8c672012-03-06 16:49:32 -0800214 case Instruction::MOVE_RESULT:
215 case Instruction::MOVE_RESULT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800216 if (mir->optimizationFlags & MIR_INLINED)
217 break; // Nop - combined w/ previous invoke
buzbee86a4bce2012-03-06 18:15:00 -0800218 storeValue(cUnit, rlDest, oatGetReturn(cUnit));
buzbeee3acd072012-02-25 17:03:10 -0800219 break;
220
Elliott Hughesadb8c672012-03-06 16:49:32 -0800221 case Instruction::MOVE:
222 case Instruction::MOVE_OBJECT:
223 case Instruction::MOVE_16:
224 case Instruction::MOVE_OBJECT_16:
225 case Instruction::MOVE_FROM16:
226 case Instruction::MOVE_OBJECT_FROM16:
buzbeee3acd072012-02-25 17:03:10 -0800227 storeValue(cUnit, rlDest, rlSrc[0]);
228 break;
229
Elliott Hughesadb8c672012-03-06 16:49:32 -0800230 case Instruction::MOVE_WIDE:
231 case Instruction::MOVE_WIDE_16:
232 case Instruction::MOVE_WIDE_FROM16:
buzbeee3acd072012-02-25 17:03:10 -0800233 storeValueWide(cUnit, rlDest, rlSrc[0]);
234 break;
235
Elliott Hughesadb8c672012-03-06 16:49:32 -0800236 case Instruction::CONST:
237 case Instruction::CONST_4:
238 case Instruction::CONST_16:
buzbeee3acd072012-02-25 17:03:10 -0800239 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
240 loadConstantNoClobber(cUnit, rlResult.lowReg, mir->dalvikInsn.vB);
241 storeValue(cUnit, rlDest, rlResult);
242 break;
243
Elliott Hughesadb8c672012-03-06 16:49:32 -0800244 case Instruction::CONST_HIGH16:
buzbeee3acd072012-02-25 17:03:10 -0800245 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
246 loadConstantNoClobber(cUnit, rlResult.lowReg,
247 mir->dalvikInsn.vB << 16);
248 storeValue(cUnit, rlDest, rlResult);
249 break;
250
Elliott Hughesadb8c672012-03-06 16:49:32 -0800251 case Instruction::CONST_WIDE_16:
252 case Instruction::CONST_WIDE_32:
buzbeee3acd072012-02-25 17:03:10 -0800253 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
254 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
255 mir->dalvikInsn.vB,
256 (mir->dalvikInsn.vB & 0x80000000) ? -1 : 0);
257 storeValueWide(cUnit, rlDest, rlResult);
258 break;
259
Elliott Hughesadb8c672012-03-06 16:49:32 -0800260 case Instruction::CONST_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800261 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
262 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
263 mir->dalvikInsn.vB_wide & 0xffffffff,
264 (mir->dalvikInsn.vB_wide >> 32) & 0xffffffff);
265 storeValueWide(cUnit, rlDest, rlResult);
266 break;
267
Elliott Hughesadb8c672012-03-06 16:49:32 -0800268 case Instruction::CONST_WIDE_HIGH16:
buzbeee3acd072012-02-25 17:03:10 -0800269 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
270 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
271 0, mir->dalvikInsn.vB << 16);
272 storeValueWide(cUnit, rlDest, rlResult);
273 break;
274
Elliott Hughesadb8c672012-03-06 16:49:32 -0800275 case Instruction::MONITOR_ENTER:
buzbeee3acd072012-02-25 17:03:10 -0800276 genMonitorEnter(cUnit, mir, rlSrc[0]);
277 break;
278
Elliott Hughesadb8c672012-03-06 16:49:32 -0800279 case Instruction::MONITOR_EXIT:
buzbeee3acd072012-02-25 17:03:10 -0800280 genMonitorExit(cUnit, mir, rlSrc[0]);
281 break;
282
Elliott Hughesadb8c672012-03-06 16:49:32 -0800283 case Instruction::CHECK_CAST:
buzbeee3acd072012-02-25 17:03:10 -0800284 genCheckCast(cUnit, mir, rlSrc[0]);
285 break;
286
Elliott Hughesadb8c672012-03-06 16:49:32 -0800287 case Instruction::INSTANCE_OF:
buzbeee3acd072012-02-25 17:03:10 -0800288 genInstanceof(cUnit, mir, rlDest, rlSrc[0]);
289 break;
290
Elliott Hughesadb8c672012-03-06 16:49:32 -0800291 case Instruction::NEW_INSTANCE:
buzbeee3acd072012-02-25 17:03:10 -0800292 genNewInstance(cUnit, mir, rlDest);
293 break;
294
Elliott Hughesadb8c672012-03-06 16:49:32 -0800295 case Instruction::THROW:
buzbeee3acd072012-02-25 17:03:10 -0800296 genThrow(cUnit, mir, rlSrc[0]);
297 break;
298
Elliott Hughesadb8c672012-03-06 16:49:32 -0800299 case Instruction::THROW_VERIFICATION_ERROR:
buzbeee3acd072012-02-25 17:03:10 -0800300 genThrowVerificationError(cUnit, mir);
301 break;
302
Elliott Hughesadb8c672012-03-06 16:49:32 -0800303 case Instruction::ARRAY_LENGTH:
buzbeee3acd072012-02-25 17:03:10 -0800304 int lenOffset;
305 lenOffset = Array::LengthOffset().Int32Value();
306 rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
307 genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, mir);
308 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
309 loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset,
310 rlResult.lowReg);
311 storeValue(cUnit, rlDest, rlResult);
312 break;
313
Elliott Hughesadb8c672012-03-06 16:49:32 -0800314 case Instruction::CONST_STRING:
315 case Instruction::CONST_STRING_JUMBO:
buzbeee3acd072012-02-25 17:03:10 -0800316 genConstString(cUnit, mir, rlDest, rlSrc[0]);
317 break;
318
Elliott Hughesadb8c672012-03-06 16:49:32 -0800319 case Instruction::CONST_CLASS:
buzbeee3acd072012-02-25 17:03:10 -0800320 genConstClass(cUnit, mir, rlDest, rlSrc[0]);
321 break;
322
Elliott Hughesadb8c672012-03-06 16:49:32 -0800323 case Instruction::FILL_ARRAY_DATA:
buzbeee3acd072012-02-25 17:03:10 -0800324 genFillArrayData(cUnit, mir, rlSrc[0]);
325 break;
326
Elliott Hughesadb8c672012-03-06 16:49:32 -0800327 case Instruction::FILLED_NEW_ARRAY:
buzbeee3acd072012-02-25 17:03:10 -0800328 genFilledNewArray(cUnit, mir, false /* not range */);
329 break;
330
Elliott Hughesadb8c672012-03-06 16:49:32 -0800331 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800332 genFilledNewArray(cUnit, mir, true /* range */);
333 break;
334
Elliott Hughesadb8c672012-03-06 16:49:32 -0800335 case Instruction::NEW_ARRAY:
buzbeee3acd072012-02-25 17:03:10 -0800336 genNewArray(cUnit, mir, rlDest, rlSrc[0]);
337 break;
338
Elliott Hughesadb8c672012-03-06 16:49:32 -0800339 case Instruction::GOTO:
340 case Instruction::GOTO_16:
341 case Instruction::GOTO_32:
buzbeee3acd072012-02-25 17:03:10 -0800342 if (bb->taken->startOffset <= mir->offset) {
343 genSuspendTest(cUnit, mir);
344 }
buzbee82488f52012-03-02 08:20:26 -0800345 opUnconditionalBranch(cUnit, &labelList[bb->taken->id]);
buzbeee3acd072012-02-25 17:03:10 -0800346 break;
347
Elliott Hughesadb8c672012-03-06 16:49:32 -0800348 case Instruction::PACKED_SWITCH:
buzbeee3acd072012-02-25 17:03:10 -0800349 genPackedSwitch(cUnit, mir, rlSrc[0]);
350 break;
351
Elliott Hughesadb8c672012-03-06 16:49:32 -0800352 case Instruction::SPARSE_SWITCH:
buzbeee3acd072012-02-25 17:03:10 -0800353 genSparseSwitch(cUnit, mir, rlSrc[0]);
354 break;
355
Elliott Hughesadb8c672012-03-06 16:49:32 -0800356 case Instruction::CMPL_FLOAT:
357 case Instruction::CMPG_FLOAT:
358 case Instruction::CMPL_DOUBLE:
359 case Instruction::CMPG_DOUBLE:
buzbeee3acd072012-02-25 17:03:10 -0800360 res = genCmpFP(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
361 break;
362
Elliott Hughesadb8c672012-03-06 16:49:32 -0800363 case Instruction::CMP_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800364 genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
365 break;
366
Elliott Hughesadb8c672012-03-06 16:49:32 -0800367 case Instruction::IF_EQ:
368 case Instruction::IF_NE:
369 case Instruction::IF_LT:
370 case Instruction::IF_GE:
371 case Instruction::IF_GT:
372 case Instruction::IF_LE: {
buzbeee3acd072012-02-25 17:03:10 -0800373 bool backwardBranch;
374 backwardBranch = (bb->taken->startOffset <= mir->offset);
375 if (backwardBranch) {
376 genSuspendTest(cUnit, mir);
377 }
378 genCompareAndBranch(cUnit, bb, mir, rlSrc[0], rlSrc[1], labelList);
379 break;
380 }
381
Elliott Hughesadb8c672012-03-06 16:49:32 -0800382 case Instruction::IF_EQZ:
383 case Instruction::IF_NEZ:
384 case Instruction::IF_LTZ:
385 case Instruction::IF_GEZ:
386 case Instruction::IF_GTZ:
387 case Instruction::IF_LEZ: {
buzbeee3acd072012-02-25 17:03:10 -0800388 bool backwardBranch;
389 backwardBranch = (bb->taken->startOffset <= mir->offset);
390 if (backwardBranch) {
391 genSuspendTest(cUnit, mir);
392 }
393 genCompareZeroAndBranch(cUnit, bb, mir, rlSrc[0], labelList);
394 break;
395 }
396
Elliott Hughesadb8c672012-03-06 16:49:32 -0800397 case Instruction::AGET_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800398 genArrayGet(cUnit, mir, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
399 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800400 case Instruction::AGET:
401 case Instruction::AGET_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800402 genArrayGet(cUnit, mir, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
403 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800404 case Instruction::AGET_BOOLEAN:
buzbeee3acd072012-02-25 17:03:10 -0800405 genArrayGet(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1],
406 rlDest, 0);
407 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800408 case Instruction::AGET_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800409 genArrayGet(cUnit, mir, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
410 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800411 case Instruction::AGET_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800412 genArrayGet(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1],
413 rlDest, 1);
414 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800415 case Instruction::AGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800416 genArrayGet(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
417 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800418 case Instruction::APUT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800419 genArrayPut(cUnit, mir, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
420 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800421 case Instruction::APUT:
buzbeee3acd072012-02-25 17:03:10 -0800422 genArrayPut(cUnit, mir, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
423 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800424 case Instruction::APUT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800425 genArrayObjPut(cUnit, mir, rlSrc[1], rlSrc[2], rlSrc[0], 2);
426 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800427 case Instruction::APUT_SHORT:
428 case Instruction::APUT_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800429 genArrayPut(cUnit, mir, kUnsignedHalf, rlSrc[1], rlSrc[2],
430 rlSrc[0], 1);
431 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800432 case Instruction::APUT_BYTE:
433 case Instruction::APUT_BOOLEAN:
buzbeee3acd072012-02-25 17:03:10 -0800434 genArrayPut(cUnit, mir, kUnsignedByte, rlSrc[1], rlSrc[2],
435 rlSrc[0], 0);
436 break;
437
Elliott Hughesadb8c672012-03-06 16:49:32 -0800438 case Instruction::IGET_OBJECT:
439 //case Instruction::IGET_OBJECT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800440 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, true);
441 break;
442
Elliott Hughesadb8c672012-03-06 16:49:32 -0800443 case Instruction::IGET_WIDE:
444 //case Instruction::IGET_WIDE_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800445 genIGet(cUnit, mir, kLong, rlDest, rlSrc[0], true, false);
446 break;
447
Elliott Hughesadb8c672012-03-06 16:49:32 -0800448 case Instruction::IGET:
449 //case Instruction::IGET_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800450 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, false);
451 break;
452
Elliott Hughesadb8c672012-03-06 16:49:32 -0800453 case Instruction::IGET_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800454 genIGet(cUnit, mir, kUnsignedHalf, rlDest, rlSrc[0], false, false);
455 break;
456
Elliott Hughesadb8c672012-03-06 16:49:32 -0800457 case Instruction::IGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800458 genIGet(cUnit, mir, kSignedHalf, rlDest, rlSrc[0], false, false);
459 break;
460
Elliott Hughesadb8c672012-03-06 16:49:32 -0800461 case Instruction::IGET_BOOLEAN:
462 case Instruction::IGET_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800463 genIGet(cUnit, mir, kUnsignedByte, rlDest, rlSrc[0], false, false);
464 break;
465
Elliott Hughesadb8c672012-03-06 16:49:32 -0800466 case Instruction::IPUT_WIDE:
467 //case Instruction::IPUT_WIDE_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800468 genIPut(cUnit, mir, kLong, rlSrc[0], rlSrc[1], true, false);
469 break;
470
Elliott Hughesadb8c672012-03-06 16:49:32 -0800471 case Instruction::IPUT_OBJECT:
472 //case Instruction::IPUT_OBJECT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800473 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, true);
474 break;
475
Elliott Hughesadb8c672012-03-06 16:49:32 -0800476 case Instruction::IPUT:
477 //case Instruction::IPUT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800478 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, false);
479 break;
480
Elliott Hughesadb8c672012-03-06 16:49:32 -0800481 case Instruction::IPUT_BOOLEAN:
482 case Instruction::IPUT_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800483 genIPut(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
484 break;
485
Elliott Hughesadb8c672012-03-06 16:49:32 -0800486 case Instruction::IPUT_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800487 genIPut(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
488 break;
489
Elliott Hughesadb8c672012-03-06 16:49:32 -0800490 case Instruction::IPUT_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800491 genIPut(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
492 break;
493
Elliott Hughesadb8c672012-03-06 16:49:32 -0800494 case Instruction::SGET_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800495 genSget(cUnit, mir, rlDest, false, true);
496 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800497 case Instruction::SGET:
498 case Instruction::SGET_BOOLEAN:
499 case Instruction::SGET_BYTE:
500 case Instruction::SGET_CHAR:
501 case Instruction::SGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800502 genSget(cUnit, mir, rlDest, false, false);
503 break;
504
Elliott Hughesadb8c672012-03-06 16:49:32 -0800505 case Instruction::SGET_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800506 genSget(cUnit, mir, rlDest, true, false);
507 break;
508
Elliott Hughesadb8c672012-03-06 16:49:32 -0800509 case Instruction::SPUT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800510 genSput(cUnit, mir, rlSrc[0], false, true);
511 break;
512
Elliott Hughesadb8c672012-03-06 16:49:32 -0800513 case Instruction::SPUT:
514 case Instruction::SPUT_BOOLEAN:
515 case Instruction::SPUT_BYTE:
516 case Instruction::SPUT_CHAR:
517 case Instruction::SPUT_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800518 genSput(cUnit, mir, rlSrc[0], false, false);
519 break;
520
Elliott Hughesadb8c672012-03-06 16:49:32 -0800521 case Instruction::SPUT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800522 genSput(cUnit, mir, rlSrc[0], true, false);
523 break;
524
Elliott Hughesadb8c672012-03-06 16:49:32 -0800525 case Instruction::INVOKE_STATIC_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800526 genInvoke(cUnit, mir, kStatic, true /*range*/);
527 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800528 case Instruction::INVOKE_STATIC:
buzbeee3acd072012-02-25 17:03:10 -0800529 genInvoke(cUnit, mir, kStatic, false /*range*/);
530 break;
531
Elliott Hughesadb8c672012-03-06 16:49:32 -0800532 case Instruction::INVOKE_DIRECT:
buzbeee3acd072012-02-25 17:03:10 -0800533 genInvoke(cUnit, mir, kDirect, false /*range*/);
534 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800535 case Instruction::INVOKE_DIRECT_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800536 genInvoke(cUnit, mir, kDirect, true /*range*/);
537 break;
538
Elliott Hughesadb8c672012-03-06 16:49:32 -0800539 case Instruction::INVOKE_VIRTUAL:
buzbeee3acd072012-02-25 17:03:10 -0800540 genInvoke(cUnit, mir, kVirtual, false /*range*/);
541 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800542 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800543 genInvoke(cUnit, mir, kVirtual, true /*range*/);
544 break;
545
Elliott Hughesadb8c672012-03-06 16:49:32 -0800546 case Instruction::INVOKE_SUPER:
buzbeee3acd072012-02-25 17:03:10 -0800547 genInvoke(cUnit, mir, kSuper, false /*range*/);
548 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800549 case Instruction::INVOKE_SUPER_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800550 genInvoke(cUnit, mir, kSuper, true /*range*/);
551 break;
552
Elliott Hughesadb8c672012-03-06 16:49:32 -0800553 case Instruction::INVOKE_INTERFACE:
buzbeee3acd072012-02-25 17:03:10 -0800554 genInvoke(cUnit, mir, kInterface, false /*range*/);
555 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800556 case Instruction::INVOKE_INTERFACE_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800557 genInvoke(cUnit, mir, kInterface, true /*range*/);
558 break;
559
Elliott Hughesadb8c672012-03-06 16:49:32 -0800560 case Instruction::NEG_INT:
561 case Instruction::NOT_INT:
buzbeee3acd072012-02-25 17:03:10 -0800562 res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
563 break;
564
Elliott Hughesadb8c672012-03-06 16:49:32 -0800565 case Instruction::NEG_LONG:
566 case Instruction::NOT_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800567 res = genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
568 break;
569
Elliott Hughesadb8c672012-03-06 16:49:32 -0800570 case Instruction::NEG_FLOAT:
buzbeee3acd072012-02-25 17:03:10 -0800571 res = genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
572 break;
573
Elliott Hughesadb8c672012-03-06 16:49:32 -0800574 case Instruction::NEG_DOUBLE:
buzbeee3acd072012-02-25 17:03:10 -0800575 res = genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
576 break;
577
Elliott Hughesadb8c672012-03-06 16:49:32 -0800578 case Instruction::INT_TO_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800579 genIntToLong(cUnit, mir, rlDest, rlSrc[0]);
580 break;
581
Elliott Hughesadb8c672012-03-06 16:49:32 -0800582 case Instruction::LONG_TO_INT:
buzbeee3acd072012-02-25 17:03:10 -0800583 rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
584 rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
585 storeValue(cUnit, rlDest, rlSrc[0]);
586 break;
587
Elliott Hughesadb8c672012-03-06 16:49:32 -0800588 case Instruction::INT_TO_BYTE:
589 case Instruction::INT_TO_SHORT:
590 case Instruction::INT_TO_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800591 genIntNarrowing(cUnit, mir, rlDest, rlSrc[0]);
592 break;
593
Elliott Hughesadb8c672012-03-06 16:49:32 -0800594 case Instruction::INT_TO_FLOAT:
595 case Instruction::INT_TO_DOUBLE:
596 case Instruction::LONG_TO_FLOAT:
597 case Instruction::LONG_TO_DOUBLE:
598 case Instruction::FLOAT_TO_INT:
599 case Instruction::FLOAT_TO_LONG:
600 case Instruction::FLOAT_TO_DOUBLE:
601 case Instruction::DOUBLE_TO_INT:
602 case Instruction::DOUBLE_TO_LONG:
603 case Instruction::DOUBLE_TO_FLOAT:
buzbeee3acd072012-02-25 17:03:10 -0800604 genConversion(cUnit, mir);
605 break;
606
Elliott Hughesadb8c672012-03-06 16:49:32 -0800607 case Instruction::ADD_INT:
608 case Instruction::SUB_INT:
609 case Instruction::MUL_INT:
610 case Instruction::DIV_INT:
611 case Instruction::REM_INT:
612 case Instruction::AND_INT:
613 case Instruction::OR_INT:
614 case Instruction::XOR_INT:
615 case Instruction::SHL_INT:
616 case Instruction::SHR_INT:
617 case Instruction::USHR_INT:
618 case Instruction::ADD_INT_2ADDR:
619 case Instruction::SUB_INT_2ADDR:
620 case Instruction::MUL_INT_2ADDR:
621 case Instruction::DIV_INT_2ADDR:
622 case Instruction::REM_INT_2ADDR:
623 case Instruction::AND_INT_2ADDR:
624 case Instruction::OR_INT_2ADDR:
625 case Instruction::XOR_INT_2ADDR:
626 case Instruction::SHL_INT_2ADDR:
627 case Instruction::SHR_INT_2ADDR:
628 case Instruction::USHR_INT_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800629 genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
630 break;
631
Elliott Hughesadb8c672012-03-06 16:49:32 -0800632 case Instruction::ADD_LONG:
633 case Instruction::SUB_LONG:
634 case Instruction::MUL_LONG:
635 case Instruction::DIV_LONG:
636 case Instruction::REM_LONG:
637 case Instruction::AND_LONG:
638 case Instruction::OR_LONG:
639 case Instruction::XOR_LONG:
640 case Instruction::ADD_LONG_2ADDR:
641 case Instruction::SUB_LONG_2ADDR:
642 case Instruction::MUL_LONG_2ADDR:
643 case Instruction::DIV_LONG_2ADDR:
644 case Instruction::REM_LONG_2ADDR:
645 case Instruction::AND_LONG_2ADDR:
646 case Instruction::OR_LONG_2ADDR:
647 case Instruction::XOR_LONG_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800648 genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
649 break;
650
Elliott Hughesadb8c672012-03-06 16:49:32 -0800651 case Instruction::SHL_LONG:
652 case Instruction::SHR_LONG:
653 case Instruction::USHR_LONG:
654 case Instruction::SHL_LONG_2ADDR:
655 case Instruction::SHR_LONG_2ADDR:
656 case Instruction::USHR_LONG_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800657 genShiftOpLong(cUnit,mir, rlDest, rlSrc[0], rlSrc[1]);
658 break;
659
Elliott Hughesadb8c672012-03-06 16:49:32 -0800660 case Instruction::ADD_FLOAT:
661 case Instruction::SUB_FLOAT:
662 case Instruction::MUL_FLOAT:
663 case Instruction::DIV_FLOAT:
664 case Instruction::REM_FLOAT:
665 case Instruction::ADD_FLOAT_2ADDR:
666 case Instruction::SUB_FLOAT_2ADDR:
667 case Instruction::MUL_FLOAT_2ADDR:
668 case Instruction::DIV_FLOAT_2ADDR:
669 case Instruction::REM_FLOAT_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800670 genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
671 break;
672
Elliott Hughesadb8c672012-03-06 16:49:32 -0800673 case Instruction::ADD_DOUBLE:
674 case Instruction::SUB_DOUBLE:
675 case Instruction::MUL_DOUBLE:
676 case Instruction::DIV_DOUBLE:
677 case Instruction::REM_DOUBLE:
678 case Instruction::ADD_DOUBLE_2ADDR:
679 case Instruction::SUB_DOUBLE_2ADDR:
680 case Instruction::MUL_DOUBLE_2ADDR:
681 case Instruction::DIV_DOUBLE_2ADDR:
682 case Instruction::REM_DOUBLE_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800683 genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
684 break;
685
Elliott Hughesadb8c672012-03-06 16:49:32 -0800686 case Instruction::RSUB_INT:
687 case Instruction::ADD_INT_LIT16:
688 case Instruction::MUL_INT_LIT16:
689 case Instruction::DIV_INT_LIT16:
690 case Instruction::REM_INT_LIT16:
691 case Instruction::AND_INT_LIT16:
692 case Instruction::OR_INT_LIT16:
693 case Instruction::XOR_INT_LIT16:
694 case Instruction::ADD_INT_LIT8:
695 case Instruction::RSUB_INT_LIT8:
696 case Instruction::MUL_INT_LIT8:
697 case Instruction::DIV_INT_LIT8:
698 case Instruction::REM_INT_LIT8:
699 case Instruction::AND_INT_LIT8:
700 case Instruction::OR_INT_LIT8:
701 case Instruction::XOR_INT_LIT8:
702 case Instruction::SHL_INT_LIT8:
703 case Instruction::SHR_INT_LIT8:
704 case Instruction::USHR_INT_LIT8:
buzbeee3acd072012-02-25 17:03:10 -0800705 genArithOpIntLit(cUnit, mir, rlDest, rlSrc[0], mir->dalvikInsn.vC);
706 break;
707
708 default:
709 res = true;
710 }
711 return res;
712}
713
buzbee31a4a6f2012-02-28 15:36:15 -0800714const char* extendedMIROpNames[kMirOpLast - kMirOpFirst] = {
buzbeee3acd072012-02-25 17:03:10 -0800715 "kMirOpPhi",
716 "kMirOpNullNRangeUpCheck",
717 "kMirOpNullNRangeDownCheck",
718 "kMirOpLowerBound",
719 "kMirOpPunt",
720 "kMirOpCheckInlinePrediction",
721};
722
723/* Extended MIR instructions like PHI */
buzbee31a4a6f2012-02-28 15:36:15 -0800724void handleExtendedMethodMIR(CompilationUnit* cUnit, MIR* mir)
buzbeee3acd072012-02-25 17:03:10 -0800725{
726 int opOffset = mir->dalvikInsn.opcode - kMirOpFirst;
727 char* msg = NULL;
728 if (cUnit->printMe) {
729 msg = (char*)oatNew(cUnit, strlen(extendedMIROpNames[opOffset]) + 1,
730 false, kAllocDebugInfo);
731 strcpy(msg, extendedMIROpNames[opOffset]);
732 }
buzbee31a4a6f2012-02-28 15:36:15 -0800733 LIR* op = newLIR1(cUnit, kPseudoExtended, (int) msg);
buzbeee3acd072012-02-25 17:03:10 -0800734
735 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
736 case kMirOpPhi: {
737 char* ssaString = NULL;
738 if (cUnit->printMe) {
739 ssaString = oatGetSSAString(cUnit, mir->ssaRep);
740 }
741 op->flags.isNop = true;
buzbee31a4a6f2012-02-28 15:36:15 -0800742 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
buzbeee3acd072012-02-25 17:03:10 -0800743 break;
744 }
745 default:
746 break;
747 }
748}
749
750/* Handle the content in each basic block */
buzbee31a4a6f2012-02-28 15:36:15 -0800751bool methodBlockCodeGen(CompilationUnit* cUnit, BasicBlock* bb)
buzbeee3acd072012-02-25 17:03:10 -0800752{
753 MIR* mir;
buzbee31a4a6f2012-02-28 15:36:15 -0800754 LIR* labelList = (LIR*) cUnit->blockLabelList;
buzbeee3acd072012-02-25 17:03:10 -0800755 int blockId = bb->id;
756
757 cUnit->curBlock = bb;
758 labelList[blockId].operands[0] = bb->startOffset;
759
760 /* Insert the block label */
buzbee31a4a6f2012-02-28 15:36:15 -0800761 labelList[blockId].opcode = kPseudoNormalBlockLabel;
buzbeee3acd072012-02-25 17:03:10 -0800762 oatAppendLIR(cUnit, (LIR*) &labelList[blockId]);
763
764 /* Reset local optimization data on block boundaries */
765 oatResetRegPool(cUnit);
766 oatClobberAllRegs(cUnit);
767 oatResetDefTracking(cUnit);
768
buzbee31a4a6f2012-02-28 15:36:15 -0800769 LIR* headLIR = NULL;
buzbeee3acd072012-02-25 17:03:10 -0800770
771 if (bb->blockType == kEntryBlock) {
772 genEntrySequence(cUnit, bb);
773 } else if (bb->blockType == kExitBlock) {
774 genExitSequence(cUnit, bb);
775 }
776
777 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
778
779 oatResetRegPool(cUnit);
780 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
781 oatClobberAllRegs(cUnit);
782 }
783
784 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
785 oatResetDefTracking(cUnit);
786 }
787
788 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
789 handleExtendedMethodMIR(cUnit, mir);
790 continue;
791 }
792
793 cUnit->currentDalvikOffset = mir->offset;
794
Elliott Hughesadb8c672012-03-06 16:49:32 -0800795 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
796 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
buzbeee3acd072012-02-25 17:03:10 -0800797
buzbee31a4a6f2012-02-28 15:36:15 -0800798 LIR* boundaryLIR;
buzbeee3acd072012-02-25 17:03:10 -0800799
800 /* Mark the beginning of a Dalvik instruction for line tracking */
801 char* instStr = cUnit->printMe ?
Elliott Hughesadb8c672012-03-06 16:49:32 -0800802 oatGetDalvikDisassembly(cUnit, mir->dalvikInsn, "") : NULL;
buzbee31a4a6f2012-02-28 15:36:15 -0800803 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
buzbeee3acd072012-02-25 17:03:10 -0800804 (intptr_t) instStr);
805 cUnit->boundaryMap.insert(std::make_pair(mir->offset,
806 (LIR*)boundaryLIR));
807 /* Remember the first LIR for this block */
808 if (headLIR == NULL) {
809 headLIR = boundaryLIR;
810 /* Set the first boundaryLIR as a scheduling barrier */
811 headLIR->defMask = ENCODE_ALL;
812 }
813
814 /* If we're compiling for the debugger, generate an update callout */
815 if (cUnit->genDebugger) {
816 genDebuggerUpdate(cUnit, mir->offset);
817 }
818
819 /* Don't generate the SSA annotation unless verbose mode is on */
820 if (cUnit->printMe && mir->ssaRep) {
821 char* ssaString = oatGetSSAString(cUnit, mir->ssaRep);
buzbee31a4a6f2012-02-28 15:36:15 -0800822 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
buzbeee3acd072012-02-25 17:03:10 -0800823 }
824
825 bool notHandled = compileDalvikInstruction(cUnit, mir, bb, labelList);
buzbeee3acd072012-02-25 17:03:10 -0800826 if (notHandled) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800827 LOG(FATAL) << StringPrintf("%#06x: Opcode %#x (%s) / Fmt %d not handled",
828 mir->offset, dalvikOpcode, Instruction::Name(dalvikOpcode), dalvikFormat);
829
buzbeee3acd072012-02-25 17:03:10 -0800830 }
831 }
832
833 if (headLIR) {
834 /*
835 * Eliminate redundant loads/stores and delay stores into later
836 * slots
837 */
838 oatApplyLocalOptimizations(cUnit, (LIR*) headLIR,
839 cUnit->lastLIRInsn);
840
841 /*
842 * Generate an unconditional branch to the fallthrough block.
843 */
844 if (bb->fallThrough) {
buzbee82488f52012-03-02 08:20:26 -0800845 opUnconditionalBranch(cUnit,
846 &labelList[bb->fallThrough->id]);
buzbeee3acd072012-02-25 17:03:10 -0800847 }
848 }
849 return false;
850}
851
852void oatMethodMIR2LIR(CompilationUnit* cUnit)
853{
854 /* Used to hold the labels of each block */
855 cUnit->blockLabelList =
buzbee31a4a6f2012-02-28 15:36:15 -0800856 (void *) oatNew(cUnit, sizeof(LIR) * cUnit->numBlocks, true,
buzbeee3acd072012-02-25 17:03:10 -0800857 kAllocLIR);
858
859 oatDataFlowAnalysisDispatcher(cUnit, methodBlockCodeGen,
860 kPreOrderDFSTraversal, false /* Iterative */);
861 handleSuspendLaunchpads(cUnit);
862
863 handleThrowLaunchpads(cUnit);
864
buzbee86a4bce2012-03-06 18:15:00 -0800865 if (!(cUnit->disableOpt & (1 << kSafeOptimizations))) {
866 removeRedundantBranches(cUnit);
867 }
buzbeee3acd072012-02-25 17:03:10 -0800868}
869
870/* Needed by the ld/st optmizatons */
buzbee31a4a6f2012-02-28 15:36:15 -0800871LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
buzbeee3acd072012-02-25 17:03:10 -0800872{
buzbee82488f52012-03-02 08:20:26 -0800873 return opRegCopyNoInsert(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -0800874}
875
876/* Needed by the register allocator */
877void oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
878{
buzbee82488f52012-03-02 08:20:26 -0800879 opRegCopy(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -0800880}
881
882/* Needed by the register allocator */
883void oatRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
884 int srcLo, int srcHi)
885{
buzbee82488f52012-03-02 08:20:26 -0800886 opRegCopyWide(cUnit, destLo, destHi, srcLo, srcHi);
buzbeee3acd072012-02-25 17:03:10 -0800887}
888
889void oatFlushRegImpl(CompilationUnit* cUnit, int rBase,
890 int displacement, int rSrc, OpSize size)
891{
892 storeBaseDisp(cUnit, rBase, displacement, rSrc, size);
893}
894
895void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase,
896 int displacement, int rSrcLo, int rSrcHi)
897{
898 storeBaseDispWide(cUnit, rBase, displacement, rSrcLo, rSrcHi);
899}
900
901} // namespace art