blob: 5baabf2f323a06c22f13aec8217513ab7448ac8c [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",
buzbeee1965672012-03-11 18:39:19 -0700719 "kMirOpCopy",
buzbeee3acd072012-02-25 17:03:10 -0800720};
721
722/* Extended MIR instructions like PHI */
buzbee31a4a6f2012-02-28 15:36:15 -0800723void handleExtendedMethodMIR(CompilationUnit* cUnit, MIR* mir)
buzbeee3acd072012-02-25 17:03:10 -0800724{
725 int opOffset = mir->dalvikInsn.opcode - kMirOpFirst;
726 char* msg = NULL;
727 if (cUnit->printMe) {
728 msg = (char*)oatNew(cUnit, strlen(extendedMIROpNames[opOffset]) + 1,
729 false, kAllocDebugInfo);
730 strcpy(msg, extendedMIROpNames[opOffset]);
731 }
buzbee31a4a6f2012-02-28 15:36:15 -0800732 LIR* op = newLIR1(cUnit, kPseudoExtended, (int) msg);
buzbeee3acd072012-02-25 17:03:10 -0800733
734 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
735 case kMirOpPhi: {
736 char* ssaString = NULL;
737 if (cUnit->printMe) {
738 ssaString = oatGetSSAString(cUnit, mir->ssaRep);
739 }
740 op->flags.isNop = true;
buzbee31a4a6f2012-02-28 15:36:15 -0800741 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
buzbeee3acd072012-02-25 17:03:10 -0800742 break;
743 }
buzbeee1965672012-03-11 18:39:19 -0700744 case kMirOpCopy:
745 UNIMPLEMENTED(FATAL) << "Need kMirOpCopy";
746 break;
buzbeee3acd072012-02-25 17:03:10 -0800747 default:
748 break;
749 }
750}
751
752/* Handle the content in each basic block */
buzbee31a4a6f2012-02-28 15:36:15 -0800753bool methodBlockCodeGen(CompilationUnit* cUnit, BasicBlock* bb)
buzbeee3acd072012-02-25 17:03:10 -0800754{
755 MIR* mir;
buzbee31a4a6f2012-02-28 15:36:15 -0800756 LIR* labelList = (LIR*) cUnit->blockLabelList;
buzbeee3acd072012-02-25 17:03:10 -0800757 int blockId = bb->id;
758
759 cUnit->curBlock = bb;
760 labelList[blockId].operands[0] = bb->startOffset;
761
762 /* Insert the block label */
buzbee31a4a6f2012-02-28 15:36:15 -0800763 labelList[blockId].opcode = kPseudoNormalBlockLabel;
buzbeee3acd072012-02-25 17:03:10 -0800764 oatAppendLIR(cUnit, (LIR*) &labelList[blockId]);
765
buzbeee1965672012-03-11 18:39:19 -0700766 /* Free temp registers and reset redundant store tracking */
buzbeee3acd072012-02-25 17:03:10 -0800767 oatResetRegPool(cUnit);
buzbeee3acd072012-02-25 17:03:10 -0800768 oatResetDefTracking(cUnit);
769
buzbeee1965672012-03-11 18:39:19 -0700770 /*
771 * If control reached us from our immediate predecessor via
772 * fallthrough and we have no other incoming arcs we can
773 * reuse existing liveness. Otherwise, reset.
774 */
775 if (!bb->fallThroughTarget || bb->predecessors->numUsed != 1) {
776 oatClobberAllRegs(cUnit);
777 }
778
buzbee31a4a6f2012-02-28 15:36:15 -0800779 LIR* headLIR = NULL;
buzbeee3acd072012-02-25 17:03:10 -0800780
781 if (bb->blockType == kEntryBlock) {
782 genEntrySequence(cUnit, bb);
783 } else if (bb->blockType == kExitBlock) {
784 genExitSequence(cUnit, bb);
785 }
786
787 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
788
789 oatResetRegPool(cUnit);
790 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
791 oatClobberAllRegs(cUnit);
792 }
793
794 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
795 oatResetDefTracking(cUnit);
796 }
797
798 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
799 handleExtendedMethodMIR(cUnit, mir);
800 continue;
801 }
802
803 cUnit->currentDalvikOffset = mir->offset;
804
Elliott Hughesadb8c672012-03-06 16:49:32 -0800805 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
806 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
buzbeee3acd072012-02-25 17:03:10 -0800807
buzbee31a4a6f2012-02-28 15:36:15 -0800808 LIR* boundaryLIR;
buzbeee3acd072012-02-25 17:03:10 -0800809
810 /* Mark the beginning of a Dalvik instruction for line tracking */
811 char* instStr = cUnit->printMe ?
Elliott Hughesadb8c672012-03-06 16:49:32 -0800812 oatGetDalvikDisassembly(cUnit, mir->dalvikInsn, "") : NULL;
buzbee31a4a6f2012-02-28 15:36:15 -0800813 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
buzbeee3acd072012-02-25 17:03:10 -0800814 (intptr_t) instStr);
815 cUnit->boundaryMap.insert(std::make_pair(mir->offset,
816 (LIR*)boundaryLIR));
817 /* Remember the first LIR for this block */
818 if (headLIR == NULL) {
819 headLIR = boundaryLIR;
820 /* Set the first boundaryLIR as a scheduling barrier */
821 headLIR->defMask = ENCODE_ALL;
822 }
823
824 /* If we're compiling for the debugger, generate an update callout */
825 if (cUnit->genDebugger) {
826 genDebuggerUpdate(cUnit, mir->offset);
827 }
828
829 /* Don't generate the SSA annotation unless verbose mode is on */
830 if (cUnit->printMe && mir->ssaRep) {
831 char* ssaString = oatGetSSAString(cUnit, mir->ssaRep);
buzbee31a4a6f2012-02-28 15:36:15 -0800832 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
buzbeee3acd072012-02-25 17:03:10 -0800833 }
834
835 bool notHandled = compileDalvikInstruction(cUnit, mir, bb, labelList);
buzbeee3acd072012-02-25 17:03:10 -0800836 if (notHandled) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800837 LOG(FATAL) << StringPrintf("%#06x: Opcode %#x (%s) / Fmt %d not handled",
838 mir->offset, dalvikOpcode, Instruction::Name(dalvikOpcode), dalvikFormat);
839
buzbeee3acd072012-02-25 17:03:10 -0800840 }
841 }
842
843 if (headLIR) {
844 /*
845 * Eliminate redundant loads/stores and delay stores into later
846 * slots
847 */
848 oatApplyLocalOptimizations(cUnit, (LIR*) headLIR,
849 cUnit->lastLIRInsn);
850
851 /*
852 * Generate an unconditional branch to the fallthrough block.
853 */
854 if (bb->fallThrough) {
buzbee82488f52012-03-02 08:20:26 -0800855 opUnconditionalBranch(cUnit,
856 &labelList[bb->fallThrough->id]);
buzbeee3acd072012-02-25 17:03:10 -0800857 }
858 }
859 return false;
860}
861
862void oatMethodMIR2LIR(CompilationUnit* cUnit)
863{
864 /* Used to hold the labels of each block */
865 cUnit->blockLabelList =
buzbee31a4a6f2012-02-28 15:36:15 -0800866 (void *) oatNew(cUnit, sizeof(LIR) * cUnit->numBlocks, true,
buzbeee3acd072012-02-25 17:03:10 -0800867 kAllocLIR);
868
869 oatDataFlowAnalysisDispatcher(cUnit, methodBlockCodeGen,
870 kPreOrderDFSTraversal, false /* Iterative */);
871 handleSuspendLaunchpads(cUnit);
872
873 handleThrowLaunchpads(cUnit);
874
buzbee86a4bce2012-03-06 18:15:00 -0800875 if (!(cUnit->disableOpt & (1 << kSafeOptimizations))) {
876 removeRedundantBranches(cUnit);
877 }
buzbeee3acd072012-02-25 17:03:10 -0800878}
879
880/* Needed by the ld/st optmizatons */
buzbee31a4a6f2012-02-28 15:36:15 -0800881LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
buzbeee3acd072012-02-25 17:03:10 -0800882{
buzbee82488f52012-03-02 08:20:26 -0800883 return opRegCopyNoInsert(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -0800884}
885
886/* Needed by the register allocator */
887void oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
888{
buzbee82488f52012-03-02 08:20:26 -0800889 opRegCopy(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -0800890}
891
892/* Needed by the register allocator */
893void oatRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
894 int srcLo, int srcHi)
895{
buzbee82488f52012-03-02 08:20:26 -0800896 opRegCopyWide(cUnit, destLo, destHi, srcLo, srcHi);
buzbeee3acd072012-02-25 17:03:10 -0800897}
898
899void oatFlushRegImpl(CompilationUnit* cUnit, int rBase,
900 int displacement, int rSrc, OpSize size)
901{
902 storeBaseDisp(cUnit, rBase, displacement, rSrc, size);
903}
904
905void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase,
906 int displacement, int rSrcLo, int rSrcHi)
907{
908 storeBaseDispWide(cUnit, rBase, displacement, rSrcLo, rSrcHi);
909}
910
911} // namespace art