blob: 8dd099e5984339baecc88569547bc2084662a0a4 [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 */
buzbee31a4a6f2012-02-28 15:36:15 -080028RegLocation getRetLocWide(CompilationUnit* cUnit)
buzbeee3acd072012-02-25 17:03:10 -080029{
30 RegLocation res = LOC_C_RETURN_WIDE;
31 oatLockTemp(cUnit, res.lowReg);
32 oatLockTemp(cUnit, res.highReg);
33 oatMarkPair(cUnit, res.lowReg, res.highReg);
34 return res;
35}
36
buzbee31a4a6f2012-02-28 15:36:15 -080037RegLocation getRetLoc(CompilationUnit* cUnit)
buzbeee3acd072012-02-25 17:03:10 -080038{
39 RegLocation res = LOC_C_RETURN;
40 oatLockTemp(cUnit, res.lowReg);
41 return res;
42}
43
buzbee31a4a6f2012-02-28 15:36:15 -080044void genInvoke(CompilationUnit* cUnit, MIR* mir, InvokeType type, bool isRange)
buzbeee3acd072012-02-25 17:03:10 -080045{
buzbeea7678db2012-03-05 15:35:46 -080046#if defined(TARGET_X86)
47 UNIMPLEMENTED(WARNING) << "genInvoke";
48#else
buzbeee3acd072012-02-25 17:03:10 -080049 DecodedInstruction* dInsn = &mir->dalvikInsn;
50 int callState = 0;
buzbee31a4a6f2012-02-28 15:36:15 -080051 LIR* nullCk;
52 LIR** pNullCk = NULL;
buzbeee3acd072012-02-25 17:03:10 -080053 NextCallInsn nextCallInsn;
54 oatFlushAllRegs(cUnit); /* Everything to home location */
55 // Explicit register usage
56 oatLockCallTemps(cUnit);
57
Logan Chien4dd96f52012-02-29 01:26:58 +080058 OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
buzbee31a4a6f2012-02-28 15:36:15 -080059 *cUnit->dex_file, *cUnit->dex_cache,
60 cUnit->code_item, cUnit->method_idx,
61 cUnit->access_flags);
Logan Chien4dd96f52012-02-29 01:26:58 +080062
buzbeee3acd072012-02-25 17:03:10 -080063 uint32_t dexMethodIdx = dInsn->vB;
64 int vtableIdx;
65 bool skipThis;
66 bool fastPath =
Logan Chien4dd96f52012-02-29 01:26:58 +080067 cUnit->compiler->ComputeInvokeInfo(dexMethodIdx, &mUnit, type,
buzbeee3acd072012-02-25 17:03:10 -080068 vtableIdx)
69 && !SLOW_INVOKE_PATH;
70 if (type == kInterface) {
71 nextCallInsn = fastPath ? nextInterfaceCallInsn
72 : nextInterfaceCallInsnWithAccessCheck;
73 skipThis = false;
74 } else if (type == kDirect) {
75 if (fastPath) {
76 pNullCk = &nullCk;
77 }
78 nextCallInsn = fastPath ? nextSDCallInsn : nextDirectCallInsnSP;
79 skipThis = false;
80 } else if (type == kStatic) {
81 nextCallInsn = fastPath ? nextSDCallInsn : nextStaticCallInsnSP;
82 skipThis = false;
83 } else if (type == kSuper) {
84 nextCallInsn = fastPath ? nextSuperCallInsn : nextSuperCallInsnSP;
85 skipThis = fastPath;
86 } else {
87 DCHECK_EQ(type, kVirtual);
88 nextCallInsn = fastPath ? nextVCallInsn : nextVCallInsnSP;
89 skipThis = fastPath;
90 }
91 if (!isRange) {
92 callState = genDalvikArgsNoRange(cUnit, mir, dInsn, callState, pNullCk,
93 nextCallInsn, dexMethodIdx,
94 vtableIdx, skipThis);
95 } else {
96 callState = genDalvikArgsRange(cUnit, mir, dInsn, callState, pNullCk,
97 nextCallInsn, dexMethodIdx, vtableIdx,
98 skipThis);
99 }
100 // Finish up any of the call sequence not interleaved in arg loading
101 while (callState >= 0) {
102 callState = nextCallInsn(cUnit, mir, callState, dexMethodIdx,
103 vtableIdx);
104 }
105 if (DISPLAY_MISSING_TARGETS) {
106 genShowTarget(cUnit);
107 }
buzbee0398c422012-03-02 15:22:47 -0800108 opReg(cUnit, kOpBlx, rINVOKE_TGT);
buzbeee3acd072012-02-25 17:03:10 -0800109 oatClobberCalleeSave(cUnit);
buzbeea7678db2012-03-05 15:35:46 -0800110#endif
buzbeee3acd072012-02-25 17:03:10 -0800111}
112
113/*
114 * Target-independent code generation. Use only high-level
115 * load/store utilities here, or target-dependent genXX() handlers
116 * when necessary.
117 */
buzbee31a4a6f2012-02-28 15:36:15 -0800118bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
119 BasicBlock* bb, LIR* labelList)
buzbeee3acd072012-02-25 17:03:10 -0800120{
121 bool res = false; // Assume success
122 RegLocation rlSrc[3];
123 RegLocation rlDest = badLoc;
124 RegLocation rlResult = badLoc;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800125 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbeee3acd072012-02-25 17:03:10 -0800126
127 /* Prep Src and Dest locations */
128 int nextSreg = 0;
129 int nextLoc = 0;
130 int attrs = oatDataFlowAttributes[opcode];
131 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
132 if (attrs & DF_UA) {
133 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
134 nextSreg++;
135 } else if (attrs & DF_UA_WIDE) {
136 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
137 nextSreg + 1);
138 nextSreg+= 2;
139 }
140 if (attrs & DF_UB) {
141 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
142 nextSreg++;
143 } else if (attrs & DF_UB_WIDE) {
144 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
145 nextSreg + 1);
146 nextSreg+= 2;
147 }
148 if (attrs & DF_UC) {
149 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
150 } else if (attrs & DF_UC_WIDE) {
151 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
152 nextSreg + 1);
153 }
154 if (attrs & DF_DA) {
155 rlDest = oatGetDest(cUnit, mir, 0);
156 } else if (attrs & DF_DA_WIDE) {
157 rlDest = oatGetDestWide(cUnit, mir, 0, 1);
158 }
159
160 switch(opcode) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800161 case Instruction::NOP:
buzbeee3acd072012-02-25 17:03:10 -0800162 break;
163
Elliott Hughesadb8c672012-03-06 16:49:32 -0800164 case Instruction::MOVE_EXCEPTION:
buzbeea7678db2012-03-05 15:35:46 -0800165#if defined(TARGET_X86)
Elliott Hughesadb8c672012-03-06 16:49:32 -0800166 UNIMPLEMENTED(WARNING) << "Instruction::MOVE_EXCEPTION";
buzbeea7678db2012-03-05 15:35:46 -0800167#else
buzbeee3acd072012-02-25 17:03:10 -0800168 int exOffset;
169 int resetReg;
170 exOffset = Thread::ExceptionOffset().Int32Value();
171 resetReg = oatAllocTemp(cUnit);
172 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
173 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
174 loadConstant(cUnit, resetReg, 0);
175 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
176 storeValue(cUnit, rlDest, rlResult);
buzbeea7678db2012-03-05 15:35:46 -0800177#endif
buzbeee3acd072012-02-25 17:03:10 -0800178 break;
179
Elliott Hughesadb8c672012-03-06 16:49:32 -0800180 case Instruction::RETURN_VOID:
buzbeee3acd072012-02-25 17:03:10 -0800181 genSuspendTest(cUnit, mir);
182 break;
183
Elliott Hughesadb8c672012-03-06 16:49:32 -0800184 case Instruction::RETURN:
185 case Instruction::RETURN_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800186 genSuspendTest(cUnit, mir);
187 storeValue(cUnit, getRetLoc(cUnit), rlSrc[0]);
188 break;
189
Elliott Hughesadb8c672012-03-06 16:49:32 -0800190 case Instruction::RETURN_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800191 genSuspendTest(cUnit, mir);
192 storeValueWide(cUnit, getRetLocWide(cUnit), rlSrc[0]);
193 break;
194
Elliott Hughesadb8c672012-03-06 16:49:32 -0800195 case Instruction::MOVE_RESULT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800196 if (mir->optimizationFlags & MIR_INLINED)
197 break; // Nop - combined w/ previous invoke
198 storeValueWide(cUnit, rlDest, getRetLocWide(cUnit));
199 break;
200
Elliott Hughesadb8c672012-03-06 16:49:32 -0800201 case Instruction::MOVE_RESULT:
202 case Instruction::MOVE_RESULT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800203 if (mir->optimizationFlags & MIR_INLINED)
204 break; // Nop - combined w/ previous invoke
205 storeValue(cUnit, rlDest, getRetLoc(cUnit));
206 break;
207
Elliott Hughesadb8c672012-03-06 16:49:32 -0800208 case Instruction::MOVE:
209 case Instruction::MOVE_OBJECT:
210 case Instruction::MOVE_16:
211 case Instruction::MOVE_OBJECT_16:
212 case Instruction::MOVE_FROM16:
213 case Instruction::MOVE_OBJECT_FROM16:
buzbeee3acd072012-02-25 17:03:10 -0800214 storeValue(cUnit, rlDest, rlSrc[0]);
215 break;
216
Elliott Hughesadb8c672012-03-06 16:49:32 -0800217 case Instruction::MOVE_WIDE:
218 case Instruction::MOVE_WIDE_16:
219 case Instruction::MOVE_WIDE_FROM16:
buzbeee3acd072012-02-25 17:03:10 -0800220 storeValueWide(cUnit, rlDest, rlSrc[0]);
221 break;
222
Elliott Hughesadb8c672012-03-06 16:49:32 -0800223 case Instruction::CONST:
224 case Instruction::CONST_4:
225 case Instruction::CONST_16:
buzbeee3acd072012-02-25 17:03:10 -0800226 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
227 loadConstantNoClobber(cUnit, rlResult.lowReg, mir->dalvikInsn.vB);
228 storeValue(cUnit, rlDest, rlResult);
229 break;
230
Elliott Hughesadb8c672012-03-06 16:49:32 -0800231 case Instruction::CONST_HIGH16:
buzbeee3acd072012-02-25 17:03:10 -0800232 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
233 loadConstantNoClobber(cUnit, rlResult.lowReg,
234 mir->dalvikInsn.vB << 16);
235 storeValue(cUnit, rlDest, rlResult);
236 break;
237
Elliott Hughesadb8c672012-03-06 16:49:32 -0800238 case Instruction::CONST_WIDE_16:
239 case Instruction::CONST_WIDE_32:
buzbeee3acd072012-02-25 17:03:10 -0800240 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
241 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
242 mir->dalvikInsn.vB,
243 (mir->dalvikInsn.vB & 0x80000000) ? -1 : 0);
244 storeValueWide(cUnit, rlDest, rlResult);
245 break;
246
Elliott Hughesadb8c672012-03-06 16:49:32 -0800247 case Instruction::CONST_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800248 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
249 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
250 mir->dalvikInsn.vB_wide & 0xffffffff,
251 (mir->dalvikInsn.vB_wide >> 32) & 0xffffffff);
252 storeValueWide(cUnit, rlDest, rlResult);
253 break;
254
Elliott Hughesadb8c672012-03-06 16:49:32 -0800255 case Instruction::CONST_WIDE_HIGH16:
buzbeee3acd072012-02-25 17:03:10 -0800256 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
257 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
258 0, mir->dalvikInsn.vB << 16);
259 storeValueWide(cUnit, rlDest, rlResult);
260 break;
261
Elliott Hughesadb8c672012-03-06 16:49:32 -0800262 case Instruction::MONITOR_ENTER:
buzbeee3acd072012-02-25 17:03:10 -0800263 genMonitorEnter(cUnit, mir, rlSrc[0]);
264 break;
265
Elliott Hughesadb8c672012-03-06 16:49:32 -0800266 case Instruction::MONITOR_EXIT:
buzbeee3acd072012-02-25 17:03:10 -0800267 genMonitorExit(cUnit, mir, rlSrc[0]);
268 break;
269
Elliott Hughesadb8c672012-03-06 16:49:32 -0800270 case Instruction::CHECK_CAST:
buzbeee3acd072012-02-25 17:03:10 -0800271 genCheckCast(cUnit, mir, rlSrc[0]);
272 break;
273
Elliott Hughesadb8c672012-03-06 16:49:32 -0800274 case Instruction::INSTANCE_OF:
buzbeee3acd072012-02-25 17:03:10 -0800275 genInstanceof(cUnit, mir, rlDest, rlSrc[0]);
276 break;
277
Elliott Hughesadb8c672012-03-06 16:49:32 -0800278 case Instruction::NEW_INSTANCE:
buzbeee3acd072012-02-25 17:03:10 -0800279 genNewInstance(cUnit, mir, rlDest);
280 break;
281
Elliott Hughesadb8c672012-03-06 16:49:32 -0800282 case Instruction::THROW:
buzbeee3acd072012-02-25 17:03:10 -0800283 genThrow(cUnit, mir, rlSrc[0]);
284 break;
285
Elliott Hughesadb8c672012-03-06 16:49:32 -0800286 case Instruction::THROW_VERIFICATION_ERROR:
buzbeee3acd072012-02-25 17:03:10 -0800287 genThrowVerificationError(cUnit, mir);
288 break;
289
Elliott Hughesadb8c672012-03-06 16:49:32 -0800290 case Instruction::ARRAY_LENGTH:
buzbeee3acd072012-02-25 17:03:10 -0800291 int lenOffset;
292 lenOffset = Array::LengthOffset().Int32Value();
293 rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
294 genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, mir);
295 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
296 loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset,
297 rlResult.lowReg);
298 storeValue(cUnit, rlDest, rlResult);
299 break;
300
Elliott Hughesadb8c672012-03-06 16:49:32 -0800301 case Instruction::CONST_STRING:
302 case Instruction::CONST_STRING_JUMBO:
buzbeee3acd072012-02-25 17:03:10 -0800303 genConstString(cUnit, mir, rlDest, rlSrc[0]);
304 break;
305
Elliott Hughesadb8c672012-03-06 16:49:32 -0800306 case Instruction::CONST_CLASS:
buzbeee3acd072012-02-25 17:03:10 -0800307 genConstClass(cUnit, mir, rlDest, rlSrc[0]);
308 break;
309
Elliott Hughesadb8c672012-03-06 16:49:32 -0800310 case Instruction::FILL_ARRAY_DATA:
buzbeee3acd072012-02-25 17:03:10 -0800311 genFillArrayData(cUnit, mir, rlSrc[0]);
312 break;
313
Elliott Hughesadb8c672012-03-06 16:49:32 -0800314 case Instruction::FILLED_NEW_ARRAY:
buzbeee3acd072012-02-25 17:03:10 -0800315 genFilledNewArray(cUnit, mir, false /* not range */);
316 break;
317
Elliott Hughesadb8c672012-03-06 16:49:32 -0800318 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800319 genFilledNewArray(cUnit, mir, true /* range */);
320 break;
321
Elliott Hughesadb8c672012-03-06 16:49:32 -0800322 case Instruction::NEW_ARRAY:
buzbeee3acd072012-02-25 17:03:10 -0800323 genNewArray(cUnit, mir, rlDest, rlSrc[0]);
324 break;
325
Elliott Hughesadb8c672012-03-06 16:49:32 -0800326 case Instruction::GOTO:
327 case Instruction::GOTO_16:
328 case Instruction::GOTO_32:
buzbeee3acd072012-02-25 17:03:10 -0800329 if (bb->taken->startOffset <= mir->offset) {
330 genSuspendTest(cUnit, mir);
331 }
buzbee82488f52012-03-02 08:20:26 -0800332 opUnconditionalBranch(cUnit, &labelList[bb->taken->id]);
buzbeee3acd072012-02-25 17:03:10 -0800333 break;
334
Elliott Hughesadb8c672012-03-06 16:49:32 -0800335 case Instruction::PACKED_SWITCH:
buzbeee3acd072012-02-25 17:03:10 -0800336 genPackedSwitch(cUnit, mir, rlSrc[0]);
337 break;
338
Elliott Hughesadb8c672012-03-06 16:49:32 -0800339 case Instruction::SPARSE_SWITCH:
buzbeee3acd072012-02-25 17:03:10 -0800340 genSparseSwitch(cUnit, mir, rlSrc[0]);
341 break;
342
Elliott Hughesadb8c672012-03-06 16:49:32 -0800343 case Instruction::CMPL_FLOAT:
344 case Instruction::CMPG_FLOAT:
345 case Instruction::CMPL_DOUBLE:
346 case Instruction::CMPG_DOUBLE:
buzbeee3acd072012-02-25 17:03:10 -0800347 res = genCmpFP(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
348 break;
349
Elliott Hughesadb8c672012-03-06 16:49:32 -0800350 case Instruction::CMP_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800351 genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
352 break;
353
Elliott Hughesadb8c672012-03-06 16:49:32 -0800354 case Instruction::IF_EQ:
355 case Instruction::IF_NE:
356 case Instruction::IF_LT:
357 case Instruction::IF_GE:
358 case Instruction::IF_GT:
359 case Instruction::IF_LE: {
buzbeee3acd072012-02-25 17:03:10 -0800360 bool backwardBranch;
361 backwardBranch = (bb->taken->startOffset <= mir->offset);
362 if (backwardBranch) {
363 genSuspendTest(cUnit, mir);
364 }
365 genCompareAndBranch(cUnit, bb, mir, rlSrc[0], rlSrc[1], labelList);
366 break;
367 }
368
Elliott Hughesadb8c672012-03-06 16:49:32 -0800369 case Instruction::IF_EQZ:
370 case Instruction::IF_NEZ:
371 case Instruction::IF_LTZ:
372 case Instruction::IF_GEZ:
373 case Instruction::IF_GTZ:
374 case Instruction::IF_LEZ: {
buzbeee3acd072012-02-25 17:03:10 -0800375 bool backwardBranch;
376 backwardBranch = (bb->taken->startOffset <= mir->offset);
377 if (backwardBranch) {
378 genSuspendTest(cUnit, mir);
379 }
380 genCompareZeroAndBranch(cUnit, bb, mir, rlSrc[0], labelList);
381 break;
382 }
383
Elliott Hughesadb8c672012-03-06 16:49:32 -0800384 case Instruction::AGET_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800385 genArrayGet(cUnit, mir, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
386 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800387 case Instruction::AGET:
388 case Instruction::AGET_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800389 genArrayGet(cUnit, mir, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
390 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800391 case Instruction::AGET_BOOLEAN:
buzbeee3acd072012-02-25 17:03:10 -0800392 genArrayGet(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1],
393 rlDest, 0);
394 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800395 case Instruction::AGET_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800396 genArrayGet(cUnit, mir, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
397 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800398 case Instruction::AGET_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800399 genArrayGet(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1],
400 rlDest, 1);
401 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800402 case Instruction::AGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800403 genArrayGet(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
404 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800405 case Instruction::APUT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800406 genArrayPut(cUnit, mir, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
407 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800408 case Instruction::APUT:
buzbeee3acd072012-02-25 17:03:10 -0800409 genArrayPut(cUnit, mir, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
410 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800411 case Instruction::APUT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800412 genArrayObjPut(cUnit, mir, rlSrc[1], rlSrc[2], rlSrc[0], 2);
413 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800414 case Instruction::APUT_SHORT:
415 case Instruction::APUT_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800416 genArrayPut(cUnit, mir, kUnsignedHalf, rlSrc[1], rlSrc[2],
417 rlSrc[0], 1);
418 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800419 case Instruction::APUT_BYTE:
420 case Instruction::APUT_BOOLEAN:
buzbeee3acd072012-02-25 17:03:10 -0800421 genArrayPut(cUnit, mir, kUnsignedByte, rlSrc[1], rlSrc[2],
422 rlSrc[0], 0);
423 break;
424
Elliott Hughesadb8c672012-03-06 16:49:32 -0800425 case Instruction::IGET_OBJECT:
426 //case Instruction::IGET_OBJECT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800427 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, true);
428 break;
429
Elliott Hughesadb8c672012-03-06 16:49:32 -0800430 case Instruction::IGET_WIDE:
431 //case Instruction::IGET_WIDE_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800432 genIGet(cUnit, mir, kLong, rlDest, rlSrc[0], true, false);
433 break;
434
Elliott Hughesadb8c672012-03-06 16:49:32 -0800435 case Instruction::IGET:
436 //case Instruction::IGET_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800437 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, false);
438 break;
439
Elliott Hughesadb8c672012-03-06 16:49:32 -0800440 case Instruction::IGET_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800441 genIGet(cUnit, mir, kUnsignedHalf, rlDest, rlSrc[0], false, false);
442 break;
443
Elliott Hughesadb8c672012-03-06 16:49:32 -0800444 case Instruction::IGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800445 genIGet(cUnit, mir, kSignedHalf, rlDest, rlSrc[0], false, false);
446 break;
447
Elliott Hughesadb8c672012-03-06 16:49:32 -0800448 case Instruction::IGET_BOOLEAN:
449 case Instruction::IGET_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800450 genIGet(cUnit, mir, kUnsignedByte, rlDest, rlSrc[0], false, false);
451 break;
452
Elliott Hughesadb8c672012-03-06 16:49:32 -0800453 case Instruction::IPUT_WIDE:
454 //case Instruction::IPUT_WIDE_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800455 genIPut(cUnit, mir, kLong, rlSrc[0], rlSrc[1], true, false);
456 break;
457
Elliott Hughesadb8c672012-03-06 16:49:32 -0800458 case Instruction::IPUT_OBJECT:
459 //case Instruction::IPUT_OBJECT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800460 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, true);
461 break;
462
Elliott Hughesadb8c672012-03-06 16:49:32 -0800463 case Instruction::IPUT:
464 //case Instruction::IPUT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800465 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, false);
466 break;
467
Elliott Hughesadb8c672012-03-06 16:49:32 -0800468 case Instruction::IPUT_BOOLEAN:
469 case Instruction::IPUT_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800470 genIPut(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
471 break;
472
Elliott Hughesadb8c672012-03-06 16:49:32 -0800473 case Instruction::IPUT_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800474 genIPut(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
475 break;
476
Elliott Hughesadb8c672012-03-06 16:49:32 -0800477 case Instruction::IPUT_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800478 genIPut(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
479 break;
480
Elliott Hughesadb8c672012-03-06 16:49:32 -0800481 case Instruction::SGET_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800482 genSget(cUnit, mir, rlDest, false, true);
483 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800484 case Instruction::SGET:
485 case Instruction::SGET_BOOLEAN:
486 case Instruction::SGET_BYTE:
487 case Instruction::SGET_CHAR:
488 case Instruction::SGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800489 genSget(cUnit, mir, rlDest, false, false);
490 break;
491
Elliott Hughesadb8c672012-03-06 16:49:32 -0800492 case Instruction::SGET_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800493 genSget(cUnit, mir, rlDest, true, false);
494 break;
495
Elliott Hughesadb8c672012-03-06 16:49:32 -0800496 case Instruction::SPUT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800497 genSput(cUnit, mir, rlSrc[0], false, true);
498 break;
499
Elliott Hughesadb8c672012-03-06 16:49:32 -0800500 case Instruction::SPUT:
501 case Instruction::SPUT_BOOLEAN:
502 case Instruction::SPUT_BYTE:
503 case Instruction::SPUT_CHAR:
504 case Instruction::SPUT_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800505 genSput(cUnit, mir, rlSrc[0], false, false);
506 break;
507
Elliott Hughesadb8c672012-03-06 16:49:32 -0800508 case Instruction::SPUT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800509 genSput(cUnit, mir, rlSrc[0], true, false);
510 break;
511
Elliott Hughesadb8c672012-03-06 16:49:32 -0800512 case Instruction::INVOKE_STATIC_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800513 genInvoke(cUnit, mir, kStatic, true /*range*/);
514 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800515 case Instruction::INVOKE_STATIC:
buzbeee3acd072012-02-25 17:03:10 -0800516 genInvoke(cUnit, mir, kStatic, false /*range*/);
517 break;
518
Elliott Hughesadb8c672012-03-06 16:49:32 -0800519 case Instruction::INVOKE_DIRECT:
buzbeee3acd072012-02-25 17:03:10 -0800520 genInvoke(cUnit, mir, kDirect, false /*range*/);
521 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800522 case Instruction::INVOKE_DIRECT_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800523 genInvoke(cUnit, mir, kDirect, true /*range*/);
524 break;
525
Elliott Hughesadb8c672012-03-06 16:49:32 -0800526 case Instruction::INVOKE_VIRTUAL:
buzbeee3acd072012-02-25 17:03:10 -0800527 genInvoke(cUnit, mir, kVirtual, false /*range*/);
528 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800529 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800530 genInvoke(cUnit, mir, kVirtual, true /*range*/);
531 break;
532
Elliott Hughesadb8c672012-03-06 16:49:32 -0800533 case Instruction::INVOKE_SUPER:
buzbeee3acd072012-02-25 17:03:10 -0800534 genInvoke(cUnit, mir, kSuper, false /*range*/);
535 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800536 case Instruction::INVOKE_SUPER_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800537 genInvoke(cUnit, mir, kSuper, true /*range*/);
538 break;
539
Elliott Hughesadb8c672012-03-06 16:49:32 -0800540 case Instruction::INVOKE_INTERFACE:
buzbeee3acd072012-02-25 17:03:10 -0800541 genInvoke(cUnit, mir, kInterface, false /*range*/);
542 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800543 case Instruction::INVOKE_INTERFACE_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800544 genInvoke(cUnit, mir, kInterface, true /*range*/);
545 break;
546
Elliott Hughesadb8c672012-03-06 16:49:32 -0800547 case Instruction::NEG_INT:
548 case Instruction::NOT_INT:
buzbeee3acd072012-02-25 17:03:10 -0800549 res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
550 break;
551
Elliott Hughesadb8c672012-03-06 16:49:32 -0800552 case Instruction::NEG_LONG:
553 case Instruction::NOT_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800554 res = genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
555 break;
556
Elliott Hughesadb8c672012-03-06 16:49:32 -0800557 case Instruction::NEG_FLOAT:
buzbeee3acd072012-02-25 17:03:10 -0800558 res = genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
559 break;
560
Elliott Hughesadb8c672012-03-06 16:49:32 -0800561 case Instruction::NEG_DOUBLE:
buzbeee3acd072012-02-25 17:03:10 -0800562 res = genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
563 break;
564
Elliott Hughesadb8c672012-03-06 16:49:32 -0800565 case Instruction::INT_TO_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800566 genIntToLong(cUnit, mir, rlDest, rlSrc[0]);
567 break;
568
Elliott Hughesadb8c672012-03-06 16:49:32 -0800569 case Instruction::LONG_TO_INT:
buzbeee3acd072012-02-25 17:03:10 -0800570 rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
571 rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
572 storeValue(cUnit, rlDest, rlSrc[0]);
573 break;
574
Elliott Hughesadb8c672012-03-06 16:49:32 -0800575 case Instruction::INT_TO_BYTE:
576 case Instruction::INT_TO_SHORT:
577 case Instruction::INT_TO_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800578 genIntNarrowing(cUnit, mir, rlDest, rlSrc[0]);
579 break;
580
Elliott Hughesadb8c672012-03-06 16:49:32 -0800581 case Instruction::INT_TO_FLOAT:
582 case Instruction::INT_TO_DOUBLE:
583 case Instruction::LONG_TO_FLOAT:
584 case Instruction::LONG_TO_DOUBLE:
585 case Instruction::FLOAT_TO_INT:
586 case Instruction::FLOAT_TO_LONG:
587 case Instruction::FLOAT_TO_DOUBLE:
588 case Instruction::DOUBLE_TO_INT:
589 case Instruction::DOUBLE_TO_LONG:
590 case Instruction::DOUBLE_TO_FLOAT:
buzbeee3acd072012-02-25 17:03:10 -0800591 genConversion(cUnit, mir);
592 break;
593
Elliott Hughesadb8c672012-03-06 16:49:32 -0800594 case Instruction::ADD_INT:
595 case Instruction::SUB_INT:
596 case Instruction::MUL_INT:
597 case Instruction::DIV_INT:
598 case Instruction::REM_INT:
599 case Instruction::AND_INT:
600 case Instruction::OR_INT:
601 case Instruction::XOR_INT:
602 case Instruction::SHL_INT:
603 case Instruction::SHR_INT:
604 case Instruction::USHR_INT:
605 case Instruction::ADD_INT_2ADDR:
606 case Instruction::SUB_INT_2ADDR:
607 case Instruction::MUL_INT_2ADDR:
608 case Instruction::DIV_INT_2ADDR:
609 case Instruction::REM_INT_2ADDR:
610 case Instruction::AND_INT_2ADDR:
611 case Instruction::OR_INT_2ADDR:
612 case Instruction::XOR_INT_2ADDR:
613 case Instruction::SHL_INT_2ADDR:
614 case Instruction::SHR_INT_2ADDR:
615 case Instruction::USHR_INT_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800616 genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
617 break;
618
Elliott Hughesadb8c672012-03-06 16:49:32 -0800619 case Instruction::ADD_LONG:
620 case Instruction::SUB_LONG:
621 case Instruction::MUL_LONG:
622 case Instruction::DIV_LONG:
623 case Instruction::REM_LONG:
624 case Instruction::AND_LONG:
625 case Instruction::OR_LONG:
626 case Instruction::XOR_LONG:
627 case Instruction::ADD_LONG_2ADDR:
628 case Instruction::SUB_LONG_2ADDR:
629 case Instruction::MUL_LONG_2ADDR:
630 case Instruction::DIV_LONG_2ADDR:
631 case Instruction::REM_LONG_2ADDR:
632 case Instruction::AND_LONG_2ADDR:
633 case Instruction::OR_LONG_2ADDR:
634 case Instruction::XOR_LONG_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800635 genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
636 break;
637
Elliott Hughesadb8c672012-03-06 16:49:32 -0800638 case Instruction::SHL_LONG:
639 case Instruction::SHR_LONG:
640 case Instruction::USHR_LONG:
641 case Instruction::SHL_LONG_2ADDR:
642 case Instruction::SHR_LONG_2ADDR:
643 case Instruction::USHR_LONG_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800644 genShiftOpLong(cUnit,mir, rlDest, rlSrc[0], rlSrc[1]);
645 break;
646
Elliott Hughesadb8c672012-03-06 16:49:32 -0800647 case Instruction::ADD_FLOAT:
648 case Instruction::SUB_FLOAT:
649 case Instruction::MUL_FLOAT:
650 case Instruction::DIV_FLOAT:
651 case Instruction::REM_FLOAT:
652 case Instruction::ADD_FLOAT_2ADDR:
653 case Instruction::SUB_FLOAT_2ADDR:
654 case Instruction::MUL_FLOAT_2ADDR:
655 case Instruction::DIV_FLOAT_2ADDR:
656 case Instruction::REM_FLOAT_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800657 genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
658 break;
659
Elliott Hughesadb8c672012-03-06 16:49:32 -0800660 case Instruction::ADD_DOUBLE:
661 case Instruction::SUB_DOUBLE:
662 case Instruction::MUL_DOUBLE:
663 case Instruction::DIV_DOUBLE:
664 case Instruction::REM_DOUBLE:
665 case Instruction::ADD_DOUBLE_2ADDR:
666 case Instruction::SUB_DOUBLE_2ADDR:
667 case Instruction::MUL_DOUBLE_2ADDR:
668 case Instruction::DIV_DOUBLE_2ADDR:
669 case Instruction::REM_DOUBLE_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800670 genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
671 break;
672
Elliott Hughesadb8c672012-03-06 16:49:32 -0800673 case Instruction::RSUB_INT:
674 case Instruction::ADD_INT_LIT16:
675 case Instruction::MUL_INT_LIT16:
676 case Instruction::DIV_INT_LIT16:
677 case Instruction::REM_INT_LIT16:
678 case Instruction::AND_INT_LIT16:
679 case Instruction::OR_INT_LIT16:
680 case Instruction::XOR_INT_LIT16:
681 case Instruction::ADD_INT_LIT8:
682 case Instruction::RSUB_INT_LIT8:
683 case Instruction::MUL_INT_LIT8:
684 case Instruction::DIV_INT_LIT8:
685 case Instruction::REM_INT_LIT8:
686 case Instruction::AND_INT_LIT8:
687 case Instruction::OR_INT_LIT8:
688 case Instruction::XOR_INT_LIT8:
689 case Instruction::SHL_INT_LIT8:
690 case Instruction::SHR_INT_LIT8:
691 case Instruction::USHR_INT_LIT8:
buzbeee3acd072012-02-25 17:03:10 -0800692 genArithOpIntLit(cUnit, mir, rlDest, rlSrc[0], mir->dalvikInsn.vC);
693 break;
694
695 default:
696 res = true;
697 }
698 return res;
699}
700
buzbee31a4a6f2012-02-28 15:36:15 -0800701const char* extendedMIROpNames[kMirOpLast - kMirOpFirst] = {
buzbeee3acd072012-02-25 17:03:10 -0800702 "kMirOpPhi",
703 "kMirOpNullNRangeUpCheck",
704 "kMirOpNullNRangeDownCheck",
705 "kMirOpLowerBound",
706 "kMirOpPunt",
707 "kMirOpCheckInlinePrediction",
708};
709
710/* Extended MIR instructions like PHI */
buzbee31a4a6f2012-02-28 15:36:15 -0800711void handleExtendedMethodMIR(CompilationUnit* cUnit, MIR* mir)
buzbeee3acd072012-02-25 17:03:10 -0800712{
713 int opOffset = mir->dalvikInsn.opcode - kMirOpFirst;
714 char* msg = NULL;
715 if (cUnit->printMe) {
716 msg = (char*)oatNew(cUnit, strlen(extendedMIROpNames[opOffset]) + 1,
717 false, kAllocDebugInfo);
718 strcpy(msg, extendedMIROpNames[opOffset]);
719 }
buzbee31a4a6f2012-02-28 15:36:15 -0800720 LIR* op = newLIR1(cUnit, kPseudoExtended, (int) msg);
buzbeee3acd072012-02-25 17:03:10 -0800721
722 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
723 case kMirOpPhi: {
724 char* ssaString = NULL;
725 if (cUnit->printMe) {
726 ssaString = oatGetSSAString(cUnit, mir->ssaRep);
727 }
728 op->flags.isNop = true;
buzbee31a4a6f2012-02-28 15:36:15 -0800729 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
buzbeee3acd072012-02-25 17:03:10 -0800730 break;
731 }
732 default:
733 break;
734 }
735}
736
737/* Handle the content in each basic block */
buzbee31a4a6f2012-02-28 15:36:15 -0800738bool methodBlockCodeGen(CompilationUnit* cUnit, BasicBlock* bb)
buzbeee3acd072012-02-25 17:03:10 -0800739{
740 MIR* mir;
buzbee31a4a6f2012-02-28 15:36:15 -0800741 LIR* labelList = (LIR*) cUnit->blockLabelList;
buzbeee3acd072012-02-25 17:03:10 -0800742 int blockId = bb->id;
743
744 cUnit->curBlock = bb;
745 labelList[blockId].operands[0] = bb->startOffset;
746
747 /* Insert the block label */
buzbee31a4a6f2012-02-28 15:36:15 -0800748 labelList[blockId].opcode = kPseudoNormalBlockLabel;
buzbeee3acd072012-02-25 17:03:10 -0800749 oatAppendLIR(cUnit, (LIR*) &labelList[blockId]);
750
751 /* Reset local optimization data on block boundaries */
752 oatResetRegPool(cUnit);
753 oatClobberAllRegs(cUnit);
754 oatResetDefTracking(cUnit);
755
buzbee31a4a6f2012-02-28 15:36:15 -0800756 LIR* headLIR = NULL;
buzbeee3acd072012-02-25 17:03:10 -0800757
758 if (bb->blockType == kEntryBlock) {
759 genEntrySequence(cUnit, bb);
760 } else if (bb->blockType == kExitBlock) {
761 genExitSequence(cUnit, bb);
762 }
763
764 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
765
766 oatResetRegPool(cUnit);
767 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
768 oatClobberAllRegs(cUnit);
769 }
770
771 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
772 oatResetDefTracking(cUnit);
773 }
774
775 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
776 handleExtendedMethodMIR(cUnit, mir);
777 continue;
778 }
779
780 cUnit->currentDalvikOffset = mir->offset;
781
Elliott Hughesadb8c672012-03-06 16:49:32 -0800782 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
783 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
buzbeee3acd072012-02-25 17:03:10 -0800784
buzbee31a4a6f2012-02-28 15:36:15 -0800785 LIR* boundaryLIR;
buzbeee3acd072012-02-25 17:03:10 -0800786
787 /* Mark the beginning of a Dalvik instruction for line tracking */
788 char* instStr = cUnit->printMe ?
Elliott Hughesadb8c672012-03-06 16:49:32 -0800789 oatGetDalvikDisassembly(cUnit, mir->dalvikInsn, "") : NULL;
buzbee31a4a6f2012-02-28 15:36:15 -0800790 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
buzbeee3acd072012-02-25 17:03:10 -0800791 (intptr_t) instStr);
792 cUnit->boundaryMap.insert(std::make_pair(mir->offset,
793 (LIR*)boundaryLIR));
794 /* Remember the first LIR for this block */
795 if (headLIR == NULL) {
796 headLIR = boundaryLIR;
797 /* Set the first boundaryLIR as a scheduling barrier */
798 headLIR->defMask = ENCODE_ALL;
799 }
800
801 /* If we're compiling for the debugger, generate an update callout */
802 if (cUnit->genDebugger) {
803 genDebuggerUpdate(cUnit, mir->offset);
804 }
805
806 /* Don't generate the SSA annotation unless verbose mode is on */
807 if (cUnit->printMe && mir->ssaRep) {
808 char* ssaString = oatGetSSAString(cUnit, mir->ssaRep);
buzbee31a4a6f2012-02-28 15:36:15 -0800809 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
buzbeee3acd072012-02-25 17:03:10 -0800810 }
811
812 bool notHandled = compileDalvikInstruction(cUnit, mir, bb, labelList);
buzbeee3acd072012-02-25 17:03:10 -0800813 if (notHandled) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800814 LOG(FATAL) << StringPrintf("%#06x: Opcode %#x (%s) / Fmt %d not handled",
815 mir->offset, dalvikOpcode, Instruction::Name(dalvikOpcode), dalvikFormat);
816
buzbeee3acd072012-02-25 17:03:10 -0800817 }
818 }
819
820 if (headLIR) {
821 /*
822 * Eliminate redundant loads/stores and delay stores into later
823 * slots
824 */
825 oatApplyLocalOptimizations(cUnit, (LIR*) headLIR,
826 cUnit->lastLIRInsn);
827
828 /*
829 * Generate an unconditional branch to the fallthrough block.
830 */
831 if (bb->fallThrough) {
buzbee82488f52012-03-02 08:20:26 -0800832 opUnconditionalBranch(cUnit,
833 &labelList[bb->fallThrough->id]);
buzbeee3acd072012-02-25 17:03:10 -0800834 }
835 }
836 return false;
837}
838
839void oatMethodMIR2LIR(CompilationUnit* cUnit)
840{
841 /* Used to hold the labels of each block */
842 cUnit->blockLabelList =
buzbee31a4a6f2012-02-28 15:36:15 -0800843 (void *) oatNew(cUnit, sizeof(LIR) * cUnit->numBlocks, true,
buzbeee3acd072012-02-25 17:03:10 -0800844 kAllocLIR);
845
846 oatDataFlowAnalysisDispatcher(cUnit, methodBlockCodeGen,
847 kPreOrderDFSTraversal, false /* Iterative */);
848 handleSuspendLaunchpads(cUnit);
849
850 handleThrowLaunchpads(cUnit);
851
852 removeRedundantBranches(cUnit);
853}
854
855/* Needed by the ld/st optmizatons */
buzbee31a4a6f2012-02-28 15:36:15 -0800856LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
buzbeee3acd072012-02-25 17:03:10 -0800857{
buzbee82488f52012-03-02 08:20:26 -0800858 return opRegCopyNoInsert(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -0800859}
860
861/* Needed by the register allocator */
862void oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
863{
buzbee82488f52012-03-02 08:20:26 -0800864 opRegCopy(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -0800865}
866
867/* Needed by the register allocator */
868void oatRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
869 int srcLo, int srcHi)
870{
buzbee82488f52012-03-02 08:20:26 -0800871 opRegCopyWide(cUnit, destLo, destHi, srcLo, srcHi);
buzbeee3acd072012-02-25 17:03:10 -0800872}
873
874void oatFlushRegImpl(CompilationUnit* cUnit, int rBase,
875 int displacement, int rSrc, OpSize size)
876{
877 storeBaseDisp(cUnit, rBase, displacement, rSrc, size);
878}
879
880void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase,
881 int displacement, int rSrcLo, int rSrcHi)
882{
883 storeBaseDispWide(cUnit, rBase, displacement, rSrcLo, rSrcHi);
884}
885
886} // namespace art