blob: eff4199405914b3140990c98a53fbd0e09e7589f [file] [log] [blame]
buzbeee3acd072012-02-25 17:03:10 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "object_utils.h"
18
19namespace art {
20
21#define DISPLAY_MISSING_TARGETS (cUnit->enableDebug & \
22 (1 << kDebugDisplayMissingTargets))
23
buzbee31a4a6f2012-02-28 15:36:15 -080024const RegLocation badLoc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0,
25 INVALID_REG, INVALID_REG, INVALID_SREG};
buzbeee3acd072012-02-25 17:03:10 -080026
27/* Mark register usage state and return long retloc */
Ian Rogersf7d9ad32012-03-13 18:45:39 -070028RegLocation oatGetReturnWide(CompilationUnit* cUnit, bool isDouble)
buzbeee3acd072012-02-25 17:03:10 -080029{
Ian Rogersf7d9ad32012-03-13 18:45:39 -070030 RegLocation gpr_res = LOC_C_RETURN_WIDE;
31 RegLocation fpr_res = LOC_C_RETURN_WIDE_DOUBLE;
32 RegLocation res = isDouble ? fpr_res : gpr_res;
buzbee86a4bce2012-03-06 18:15:00 -080033 oatClobber(cUnit, res.lowReg);
34 oatClobber(cUnit, res.highReg);
buzbeee3acd072012-02-25 17:03:10 -080035 oatLockTemp(cUnit, res.lowReg);
36 oatLockTemp(cUnit, res.highReg);
37 oatMarkPair(cUnit, res.lowReg, res.highReg);
38 return res;
39}
40
Ian Rogersf7d9ad32012-03-13 18:45:39 -070041RegLocation oatGetReturn(CompilationUnit* cUnit, bool isFloat)
buzbeee3acd072012-02-25 17:03:10 -080042{
Ian Rogersf7d9ad32012-03-13 18:45:39 -070043 RegLocation gpr_res = LOC_C_RETURN;
44 RegLocation fpr_res = LOC_C_RETURN_FLOAT;
45 RegLocation res = isFloat ? fpr_res : gpr_res;
buzbee86a4bce2012-03-06 18:15:00 -080046 oatClobber(cUnit, res.lowReg);
Elliott Hughesb3cd1222012-03-09 16:00:38 -080047 if (cUnit->instructionSet == kMips) {
48 oatMarkInUse(cUnit, res.lowReg);
49 } else {
50 oatLockTemp(cUnit, res.lowReg);
51 }
buzbeee3acd072012-02-25 17:03:10 -080052 return res;
53}
54
buzbee31a4a6f2012-02-28 15:36:15 -080055void genInvoke(CompilationUnit* cUnit, MIR* mir, InvokeType type, bool isRange)
buzbeee3acd072012-02-25 17:03:10 -080056{
buzbeea7678db2012-03-05 15:35:46 -080057#if defined(TARGET_X86)
58 UNIMPLEMENTED(WARNING) << "genInvoke";
59#else
buzbeee3acd072012-02-25 17:03:10 -080060 DecodedInstruction* dInsn = &mir->dalvikInsn;
61 int callState = 0;
buzbee31a4a6f2012-02-28 15:36:15 -080062 LIR* nullCk;
63 LIR** pNullCk = NULL;
buzbeee3acd072012-02-25 17:03:10 -080064 NextCallInsn nextCallInsn;
65 oatFlushAllRegs(cUnit); /* Everything to home location */
66 // Explicit register usage
67 oatLockCallTemps(cUnit);
68
Logan Chien4dd96f52012-02-29 01:26:58 +080069 OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
buzbee31a4a6f2012-02-28 15:36:15 -080070 *cUnit->dex_file, *cUnit->dex_cache,
71 cUnit->code_item, cUnit->method_idx,
72 cUnit->access_flags);
Logan Chien4dd96f52012-02-29 01:26:58 +080073
buzbeee3acd072012-02-25 17:03:10 -080074 uint32_t dexMethodIdx = dInsn->vB;
75 int vtableIdx;
76 bool skipThis;
77 bool fastPath =
Logan Chien4dd96f52012-02-29 01:26:58 +080078 cUnit->compiler->ComputeInvokeInfo(dexMethodIdx, &mUnit, type,
buzbeee3acd072012-02-25 17:03:10 -080079 vtableIdx)
80 && !SLOW_INVOKE_PATH;
81 if (type == kInterface) {
82 nextCallInsn = fastPath ? nextInterfaceCallInsn
83 : nextInterfaceCallInsnWithAccessCheck;
84 skipThis = false;
85 } else if (type == kDirect) {
86 if (fastPath) {
87 pNullCk = &nullCk;
88 }
89 nextCallInsn = fastPath ? nextSDCallInsn : nextDirectCallInsnSP;
90 skipThis = false;
91 } else if (type == kStatic) {
92 nextCallInsn = fastPath ? nextSDCallInsn : nextStaticCallInsnSP;
93 skipThis = false;
94 } else if (type == kSuper) {
95 nextCallInsn = fastPath ? nextSuperCallInsn : nextSuperCallInsnSP;
96 skipThis = fastPath;
97 } else {
98 DCHECK_EQ(type, kVirtual);
99 nextCallInsn = fastPath ? nextVCallInsn : nextVCallInsnSP;
100 skipThis = fastPath;
101 }
102 if (!isRange) {
103 callState = genDalvikArgsNoRange(cUnit, mir, dInsn, callState, pNullCk,
104 nextCallInsn, dexMethodIdx,
105 vtableIdx, skipThis);
106 } else {
107 callState = genDalvikArgsRange(cUnit, mir, dInsn, callState, pNullCk,
108 nextCallInsn, dexMethodIdx, vtableIdx,
109 skipThis);
110 }
111 // Finish up any of the call sequence not interleaved in arg loading
112 while (callState >= 0) {
113 callState = nextCallInsn(cUnit, mir, callState, dexMethodIdx,
114 vtableIdx);
115 }
116 if (DISPLAY_MISSING_TARGETS) {
117 genShowTarget(cUnit);
118 }
buzbee0398c422012-03-02 15:22:47 -0800119 opReg(cUnit, kOpBlx, rINVOKE_TGT);
buzbeee3acd072012-02-25 17:03:10 -0800120 oatClobberCalleeSave(cUnit);
buzbeea7678db2012-03-05 15:35:46 -0800121#endif
buzbeee3acd072012-02-25 17:03:10 -0800122}
123
124/*
125 * Target-independent code generation. Use only high-level
126 * load/store utilities here, or target-dependent genXX() handlers
127 * when necessary.
128 */
buzbee31a4a6f2012-02-28 15:36:15 -0800129bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
130 BasicBlock* bb, LIR* labelList)
buzbeee3acd072012-02-25 17:03:10 -0800131{
132 bool res = false; // Assume success
133 RegLocation rlSrc[3];
134 RegLocation rlDest = badLoc;
135 RegLocation rlResult = badLoc;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800136 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbeee3acd072012-02-25 17:03:10 -0800137
138 /* Prep Src and Dest locations */
139 int nextSreg = 0;
140 int nextLoc = 0;
141 int attrs = oatDataFlowAttributes[opcode];
142 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
143 if (attrs & DF_UA) {
144 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
145 nextSreg++;
146 } else if (attrs & DF_UA_WIDE) {
147 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
148 nextSreg + 1);
149 nextSreg+= 2;
150 }
151 if (attrs & DF_UB) {
152 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
153 nextSreg++;
154 } else if (attrs & DF_UB_WIDE) {
155 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
156 nextSreg + 1);
157 nextSreg+= 2;
158 }
159 if (attrs & DF_UC) {
160 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
161 } else if (attrs & DF_UC_WIDE) {
162 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
163 nextSreg + 1);
164 }
165 if (attrs & DF_DA) {
166 rlDest = oatGetDest(cUnit, mir, 0);
167 } else if (attrs & DF_DA_WIDE) {
168 rlDest = oatGetDestWide(cUnit, mir, 0, 1);
169 }
170
171 switch(opcode) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800172 case Instruction::NOP:
buzbeee3acd072012-02-25 17:03:10 -0800173 break;
174
Elliott Hughesadb8c672012-03-06 16:49:32 -0800175 case Instruction::MOVE_EXCEPTION:
buzbeea7678db2012-03-05 15:35:46 -0800176#if defined(TARGET_X86)
Elliott Hughesadb8c672012-03-06 16:49:32 -0800177 UNIMPLEMENTED(WARNING) << "Instruction::MOVE_EXCEPTION";
buzbeea7678db2012-03-05 15:35:46 -0800178#else
buzbeee3acd072012-02-25 17:03:10 -0800179 int exOffset;
180 int resetReg;
181 exOffset = Thread::ExceptionOffset().Int32Value();
182 resetReg = oatAllocTemp(cUnit);
183 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
184 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
185 loadConstant(cUnit, resetReg, 0);
186 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
187 storeValue(cUnit, rlDest, rlResult);
buzbeea7678db2012-03-05 15:35:46 -0800188#endif
buzbeee3acd072012-02-25 17:03:10 -0800189 break;
190
Elliott Hughesadb8c672012-03-06 16:49:32 -0800191 case Instruction::RETURN_VOID:
buzbee86a4bce2012-03-06 18:15:00 -0800192 if (!cUnit->attrs & METHOD_IS_LEAF) {
193 genSuspendTest(cUnit, mir);
194 }
buzbeee3acd072012-02-25 17:03:10 -0800195 break;
196
Elliott Hughesadb8c672012-03-06 16:49:32 -0800197 case Instruction::RETURN:
198 case Instruction::RETURN_OBJECT:
buzbee86a4bce2012-03-06 18:15:00 -0800199 if (!cUnit->attrs & METHOD_IS_LEAF) {
200 genSuspendTest(cUnit, mir);
201 }
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700202 storeValue(cUnit, oatGetReturn(cUnit, cUnit->shorty[0] == 'F'),
203 rlSrc[0]);
buzbeee3acd072012-02-25 17:03:10 -0800204 break;
205
Elliott Hughesadb8c672012-03-06 16:49:32 -0800206 case Instruction::RETURN_WIDE:
buzbee86a4bce2012-03-06 18:15:00 -0800207 if (!cUnit->attrs & METHOD_IS_LEAF) {
208 genSuspendTest(cUnit, mir);
209 }
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700210 storeValueWide(cUnit, oatGetReturnWide(cUnit,
211 cUnit->shorty[0] == 'D'), rlSrc[0]);
buzbeee3acd072012-02-25 17:03:10 -0800212 break;
213
Elliott Hughesadb8c672012-03-06 16:49:32 -0800214 case Instruction::MOVE_RESULT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800215 if (mir->optimizationFlags & MIR_INLINED)
216 break; // Nop - combined w/ previous invoke
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700217 storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit, rlDest.fp));
buzbeee3acd072012-02-25 17:03:10 -0800218 break;
219
Elliott Hughesadb8c672012-03-06 16:49:32 -0800220 case Instruction::MOVE_RESULT:
221 case Instruction::MOVE_RESULT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800222 if (mir->optimizationFlags & MIR_INLINED)
223 break; // Nop - combined w/ previous invoke
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700224 storeValue(cUnit, rlDest, oatGetReturn(cUnit, rlDest.fp));
buzbeee3acd072012-02-25 17:03:10 -0800225 break;
226
Elliott Hughesadb8c672012-03-06 16:49:32 -0800227 case Instruction::MOVE:
228 case Instruction::MOVE_OBJECT:
229 case Instruction::MOVE_16:
230 case Instruction::MOVE_OBJECT_16:
231 case Instruction::MOVE_FROM16:
232 case Instruction::MOVE_OBJECT_FROM16:
buzbeee3acd072012-02-25 17:03:10 -0800233 storeValue(cUnit, rlDest, rlSrc[0]);
234 break;
235
Elliott Hughesadb8c672012-03-06 16:49:32 -0800236 case Instruction::MOVE_WIDE:
237 case Instruction::MOVE_WIDE_16:
238 case Instruction::MOVE_WIDE_FROM16:
buzbeee3acd072012-02-25 17:03:10 -0800239 storeValueWide(cUnit, rlDest, rlSrc[0]);
240 break;
241
Elliott Hughesadb8c672012-03-06 16:49:32 -0800242 case Instruction::CONST:
243 case Instruction::CONST_4:
244 case Instruction::CONST_16:
buzbeee3acd072012-02-25 17:03:10 -0800245 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
246 loadConstantNoClobber(cUnit, rlResult.lowReg, mir->dalvikInsn.vB);
247 storeValue(cUnit, rlDest, rlResult);
248 break;
249
Elliott Hughesadb8c672012-03-06 16:49:32 -0800250 case Instruction::CONST_HIGH16:
buzbeee3acd072012-02-25 17:03:10 -0800251 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
252 loadConstantNoClobber(cUnit, rlResult.lowReg,
253 mir->dalvikInsn.vB << 16);
254 storeValue(cUnit, rlDest, rlResult);
255 break;
256
Elliott Hughesadb8c672012-03-06 16:49:32 -0800257 case Instruction::CONST_WIDE_16:
258 case Instruction::CONST_WIDE_32:
buzbeee3acd072012-02-25 17:03:10 -0800259 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
260 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
261 mir->dalvikInsn.vB,
262 (mir->dalvikInsn.vB & 0x80000000) ? -1 : 0);
263 storeValueWide(cUnit, rlDest, rlResult);
264 break;
265
Elliott Hughesadb8c672012-03-06 16:49:32 -0800266 case Instruction::CONST_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800267 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
268 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
269 mir->dalvikInsn.vB_wide & 0xffffffff,
270 (mir->dalvikInsn.vB_wide >> 32) & 0xffffffff);
271 storeValueWide(cUnit, rlDest, rlResult);
272 break;
273
Elliott Hughesadb8c672012-03-06 16:49:32 -0800274 case Instruction::CONST_WIDE_HIGH16:
buzbeee3acd072012-02-25 17:03:10 -0800275 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
276 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
277 0, mir->dalvikInsn.vB << 16);
278 storeValueWide(cUnit, rlDest, rlResult);
279 break;
280
Elliott Hughesadb8c672012-03-06 16:49:32 -0800281 case Instruction::MONITOR_ENTER:
buzbeee3acd072012-02-25 17:03:10 -0800282 genMonitorEnter(cUnit, mir, rlSrc[0]);
283 break;
284
Elliott Hughesadb8c672012-03-06 16:49:32 -0800285 case Instruction::MONITOR_EXIT:
buzbeee3acd072012-02-25 17:03:10 -0800286 genMonitorExit(cUnit, mir, rlSrc[0]);
287 break;
288
Elliott Hughesadb8c672012-03-06 16:49:32 -0800289 case Instruction::CHECK_CAST:
buzbeee3acd072012-02-25 17:03:10 -0800290 genCheckCast(cUnit, mir, rlSrc[0]);
291 break;
292
Elliott Hughesadb8c672012-03-06 16:49:32 -0800293 case Instruction::INSTANCE_OF:
buzbeee3acd072012-02-25 17:03:10 -0800294 genInstanceof(cUnit, mir, rlDest, rlSrc[0]);
295 break;
296
Elliott Hughesadb8c672012-03-06 16:49:32 -0800297 case Instruction::NEW_INSTANCE:
buzbeee3acd072012-02-25 17:03:10 -0800298 genNewInstance(cUnit, mir, rlDest);
299 break;
300
Elliott Hughesadb8c672012-03-06 16:49:32 -0800301 case Instruction::THROW:
buzbeee3acd072012-02-25 17:03:10 -0800302 genThrow(cUnit, mir, rlSrc[0]);
303 break;
304
Elliott Hughesadb8c672012-03-06 16:49:32 -0800305 case Instruction::THROW_VERIFICATION_ERROR:
buzbeee3acd072012-02-25 17:03:10 -0800306 genThrowVerificationError(cUnit, mir);
307 break;
308
Elliott Hughesadb8c672012-03-06 16:49:32 -0800309 case Instruction::ARRAY_LENGTH:
buzbeee3acd072012-02-25 17:03:10 -0800310 int lenOffset;
311 lenOffset = Array::LengthOffset().Int32Value();
312 rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
313 genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, mir);
314 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
315 loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset,
316 rlResult.lowReg);
317 storeValue(cUnit, rlDest, rlResult);
318 break;
319
Elliott Hughesadb8c672012-03-06 16:49:32 -0800320 case Instruction::CONST_STRING:
321 case Instruction::CONST_STRING_JUMBO:
buzbeee3acd072012-02-25 17:03:10 -0800322 genConstString(cUnit, mir, rlDest, rlSrc[0]);
323 break;
324
Elliott Hughesadb8c672012-03-06 16:49:32 -0800325 case Instruction::CONST_CLASS:
buzbeee3acd072012-02-25 17:03:10 -0800326 genConstClass(cUnit, mir, rlDest, rlSrc[0]);
327 break;
328
Elliott Hughesadb8c672012-03-06 16:49:32 -0800329 case Instruction::FILL_ARRAY_DATA:
buzbeee3acd072012-02-25 17:03:10 -0800330 genFillArrayData(cUnit, mir, rlSrc[0]);
331 break;
332
Elliott Hughesadb8c672012-03-06 16:49:32 -0800333 case Instruction::FILLED_NEW_ARRAY:
buzbeee3acd072012-02-25 17:03:10 -0800334 genFilledNewArray(cUnit, mir, false /* not range */);
335 break;
336
Elliott Hughesadb8c672012-03-06 16:49:32 -0800337 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800338 genFilledNewArray(cUnit, mir, true /* range */);
339 break;
340
Elliott Hughesadb8c672012-03-06 16:49:32 -0800341 case Instruction::NEW_ARRAY:
buzbeee3acd072012-02-25 17:03:10 -0800342 genNewArray(cUnit, mir, rlDest, rlSrc[0]);
343 break;
344
Elliott Hughesadb8c672012-03-06 16:49:32 -0800345 case Instruction::GOTO:
346 case Instruction::GOTO_16:
347 case Instruction::GOTO_32:
buzbeee3acd072012-02-25 17:03:10 -0800348 if (bb->taken->startOffset <= mir->offset) {
349 genSuspendTest(cUnit, mir);
350 }
buzbee82488f52012-03-02 08:20:26 -0800351 opUnconditionalBranch(cUnit, &labelList[bb->taken->id]);
buzbeee3acd072012-02-25 17:03:10 -0800352 break;
353
Elliott Hughesadb8c672012-03-06 16:49:32 -0800354 case Instruction::PACKED_SWITCH:
buzbeee3acd072012-02-25 17:03:10 -0800355 genPackedSwitch(cUnit, mir, rlSrc[0]);
356 break;
357
Elliott Hughesadb8c672012-03-06 16:49:32 -0800358 case Instruction::SPARSE_SWITCH:
buzbeee3acd072012-02-25 17:03:10 -0800359 genSparseSwitch(cUnit, mir, rlSrc[0]);
360 break;
361
Elliott Hughesadb8c672012-03-06 16:49:32 -0800362 case Instruction::CMPL_FLOAT:
363 case Instruction::CMPG_FLOAT:
364 case Instruction::CMPL_DOUBLE:
365 case Instruction::CMPG_DOUBLE:
buzbeee3acd072012-02-25 17:03:10 -0800366 res = genCmpFP(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
367 break;
368
Elliott Hughesadb8c672012-03-06 16:49:32 -0800369 case Instruction::CMP_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800370 genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
371 break;
372
Elliott Hughesadb8c672012-03-06 16:49:32 -0800373 case Instruction::IF_EQ:
374 case Instruction::IF_NE:
375 case Instruction::IF_LT:
376 case Instruction::IF_GE:
377 case Instruction::IF_GT:
378 case Instruction::IF_LE: {
buzbeee3acd072012-02-25 17:03:10 -0800379 bool backwardBranch;
380 backwardBranch = (bb->taken->startOffset <= mir->offset);
381 if (backwardBranch) {
382 genSuspendTest(cUnit, mir);
383 }
384 genCompareAndBranch(cUnit, bb, mir, rlSrc[0], rlSrc[1], labelList);
385 break;
386 }
387
Elliott Hughesadb8c672012-03-06 16:49:32 -0800388 case Instruction::IF_EQZ:
389 case Instruction::IF_NEZ:
390 case Instruction::IF_LTZ:
391 case Instruction::IF_GEZ:
392 case Instruction::IF_GTZ:
393 case Instruction::IF_LEZ: {
buzbeee3acd072012-02-25 17:03:10 -0800394 bool backwardBranch;
395 backwardBranch = (bb->taken->startOffset <= mir->offset);
396 if (backwardBranch) {
397 genSuspendTest(cUnit, mir);
398 }
399 genCompareZeroAndBranch(cUnit, bb, mir, rlSrc[0], labelList);
400 break;
401 }
402
Elliott Hughesadb8c672012-03-06 16:49:32 -0800403 case Instruction::AGET_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800404 genArrayGet(cUnit, mir, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
405 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800406 case Instruction::AGET:
407 case Instruction::AGET_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800408 genArrayGet(cUnit, mir, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
409 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800410 case Instruction::AGET_BOOLEAN:
buzbeee3acd072012-02-25 17:03:10 -0800411 genArrayGet(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1],
412 rlDest, 0);
413 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800414 case Instruction::AGET_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800415 genArrayGet(cUnit, mir, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
416 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800417 case Instruction::AGET_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800418 genArrayGet(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1],
419 rlDest, 1);
420 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800421 case Instruction::AGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800422 genArrayGet(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
423 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800424 case Instruction::APUT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800425 genArrayPut(cUnit, mir, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
426 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800427 case Instruction::APUT:
buzbeee3acd072012-02-25 17:03:10 -0800428 genArrayPut(cUnit, mir, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
429 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800430 case Instruction::APUT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800431 genArrayObjPut(cUnit, mir, rlSrc[1], rlSrc[2], rlSrc[0], 2);
432 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800433 case Instruction::APUT_SHORT:
434 case Instruction::APUT_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800435 genArrayPut(cUnit, mir, kUnsignedHalf, rlSrc[1], rlSrc[2],
436 rlSrc[0], 1);
437 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800438 case Instruction::APUT_BYTE:
439 case Instruction::APUT_BOOLEAN:
buzbeee3acd072012-02-25 17:03:10 -0800440 genArrayPut(cUnit, mir, kUnsignedByte, rlSrc[1], rlSrc[2],
441 rlSrc[0], 0);
442 break;
443
Elliott Hughesadb8c672012-03-06 16:49:32 -0800444 case Instruction::IGET_OBJECT:
445 //case Instruction::IGET_OBJECT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800446 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, true);
447 break;
448
Elliott Hughesadb8c672012-03-06 16:49:32 -0800449 case Instruction::IGET_WIDE:
450 //case Instruction::IGET_WIDE_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800451 genIGet(cUnit, mir, kLong, rlDest, rlSrc[0], true, false);
452 break;
453
Elliott Hughesadb8c672012-03-06 16:49:32 -0800454 case Instruction::IGET:
455 //case Instruction::IGET_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800456 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, false);
457 break;
458
Elliott Hughesadb8c672012-03-06 16:49:32 -0800459 case Instruction::IGET_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800460 genIGet(cUnit, mir, kUnsignedHalf, rlDest, rlSrc[0], false, false);
461 break;
462
Elliott Hughesadb8c672012-03-06 16:49:32 -0800463 case Instruction::IGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800464 genIGet(cUnit, mir, kSignedHalf, rlDest, rlSrc[0], false, false);
465 break;
466
Elliott Hughesadb8c672012-03-06 16:49:32 -0800467 case Instruction::IGET_BOOLEAN:
468 case Instruction::IGET_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800469 genIGet(cUnit, mir, kUnsignedByte, rlDest, rlSrc[0], false, false);
470 break;
471
Elliott Hughesadb8c672012-03-06 16:49:32 -0800472 case Instruction::IPUT_WIDE:
473 //case Instruction::IPUT_WIDE_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800474 genIPut(cUnit, mir, kLong, rlSrc[0], rlSrc[1], true, false);
475 break;
476
Elliott Hughesadb8c672012-03-06 16:49:32 -0800477 case Instruction::IPUT_OBJECT:
478 //case Instruction::IPUT_OBJECT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800479 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, true);
480 break;
481
Elliott Hughesadb8c672012-03-06 16:49:32 -0800482 case Instruction::IPUT:
483 //case Instruction::IPUT_VOLATILE:
buzbeee3acd072012-02-25 17:03:10 -0800484 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, false);
485 break;
486
Elliott Hughesadb8c672012-03-06 16:49:32 -0800487 case Instruction::IPUT_BOOLEAN:
488 case Instruction::IPUT_BYTE:
buzbeee3acd072012-02-25 17:03:10 -0800489 genIPut(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
490 break;
491
Elliott Hughesadb8c672012-03-06 16:49:32 -0800492 case Instruction::IPUT_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800493 genIPut(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
494 break;
495
Elliott Hughesadb8c672012-03-06 16:49:32 -0800496 case Instruction::IPUT_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800497 genIPut(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
498 break;
499
Elliott Hughesadb8c672012-03-06 16:49:32 -0800500 case Instruction::SGET_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800501 genSget(cUnit, mir, rlDest, false, true);
502 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800503 case Instruction::SGET:
504 case Instruction::SGET_BOOLEAN:
505 case Instruction::SGET_BYTE:
506 case Instruction::SGET_CHAR:
507 case Instruction::SGET_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800508 genSget(cUnit, mir, rlDest, false, false);
509 break;
510
Elliott Hughesadb8c672012-03-06 16:49:32 -0800511 case Instruction::SGET_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800512 genSget(cUnit, mir, rlDest, true, false);
513 break;
514
Elliott Hughesadb8c672012-03-06 16:49:32 -0800515 case Instruction::SPUT_OBJECT:
buzbeee3acd072012-02-25 17:03:10 -0800516 genSput(cUnit, mir, rlSrc[0], false, true);
517 break;
518
Elliott Hughesadb8c672012-03-06 16:49:32 -0800519 case Instruction::SPUT:
520 case Instruction::SPUT_BOOLEAN:
521 case Instruction::SPUT_BYTE:
522 case Instruction::SPUT_CHAR:
523 case Instruction::SPUT_SHORT:
buzbeee3acd072012-02-25 17:03:10 -0800524 genSput(cUnit, mir, rlSrc[0], false, false);
525 break;
526
Elliott Hughesadb8c672012-03-06 16:49:32 -0800527 case Instruction::SPUT_WIDE:
buzbeee3acd072012-02-25 17:03:10 -0800528 genSput(cUnit, mir, rlSrc[0], true, false);
529 break;
530
Elliott Hughesadb8c672012-03-06 16:49:32 -0800531 case Instruction::INVOKE_STATIC_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800532 genInvoke(cUnit, mir, kStatic, true /*range*/);
533 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800534 case Instruction::INVOKE_STATIC:
buzbeee3acd072012-02-25 17:03:10 -0800535 genInvoke(cUnit, mir, kStatic, false /*range*/);
536 break;
537
Elliott Hughesadb8c672012-03-06 16:49:32 -0800538 case Instruction::INVOKE_DIRECT:
buzbeee3acd072012-02-25 17:03:10 -0800539 genInvoke(cUnit, mir, kDirect, false /*range*/);
540 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800541 case Instruction::INVOKE_DIRECT_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800542 genInvoke(cUnit, mir, kDirect, true /*range*/);
543 break;
544
Elliott Hughesadb8c672012-03-06 16:49:32 -0800545 case Instruction::INVOKE_VIRTUAL:
buzbeee3acd072012-02-25 17:03:10 -0800546 genInvoke(cUnit, mir, kVirtual, false /*range*/);
547 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800548 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800549 genInvoke(cUnit, mir, kVirtual, true /*range*/);
550 break;
551
Elliott Hughesadb8c672012-03-06 16:49:32 -0800552 case Instruction::INVOKE_SUPER:
buzbeee3acd072012-02-25 17:03:10 -0800553 genInvoke(cUnit, mir, kSuper, false /*range*/);
554 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800555 case Instruction::INVOKE_SUPER_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800556 genInvoke(cUnit, mir, kSuper, true /*range*/);
557 break;
558
Elliott Hughesadb8c672012-03-06 16:49:32 -0800559 case Instruction::INVOKE_INTERFACE:
buzbeee3acd072012-02-25 17:03:10 -0800560 genInvoke(cUnit, mir, kInterface, false /*range*/);
561 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800562 case Instruction::INVOKE_INTERFACE_RANGE:
buzbeee3acd072012-02-25 17:03:10 -0800563 genInvoke(cUnit, mir, kInterface, true /*range*/);
564 break;
565
Elliott Hughesadb8c672012-03-06 16:49:32 -0800566 case Instruction::NEG_INT:
567 case Instruction::NOT_INT:
buzbeee3acd072012-02-25 17:03:10 -0800568 res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
569 break;
570
Elliott Hughesadb8c672012-03-06 16:49:32 -0800571 case Instruction::NEG_LONG:
572 case Instruction::NOT_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800573 res = genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
574 break;
575
Elliott Hughesadb8c672012-03-06 16:49:32 -0800576 case Instruction::NEG_FLOAT:
buzbeee3acd072012-02-25 17:03:10 -0800577 res = genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
578 break;
579
Elliott Hughesadb8c672012-03-06 16:49:32 -0800580 case Instruction::NEG_DOUBLE:
buzbeee3acd072012-02-25 17:03:10 -0800581 res = genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
582 break;
583
Elliott Hughesadb8c672012-03-06 16:49:32 -0800584 case Instruction::INT_TO_LONG:
buzbeee3acd072012-02-25 17:03:10 -0800585 genIntToLong(cUnit, mir, rlDest, rlSrc[0]);
586 break;
587
Elliott Hughesadb8c672012-03-06 16:49:32 -0800588 case Instruction::LONG_TO_INT:
buzbeee3acd072012-02-25 17:03:10 -0800589 rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
590 rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
591 storeValue(cUnit, rlDest, rlSrc[0]);
592 break;
593
Elliott Hughesadb8c672012-03-06 16:49:32 -0800594 case Instruction::INT_TO_BYTE:
595 case Instruction::INT_TO_SHORT:
596 case Instruction::INT_TO_CHAR:
buzbeee3acd072012-02-25 17:03:10 -0800597 genIntNarrowing(cUnit, mir, rlDest, rlSrc[0]);
598 break;
599
Elliott Hughesadb8c672012-03-06 16:49:32 -0800600 case Instruction::INT_TO_FLOAT:
601 case Instruction::INT_TO_DOUBLE:
602 case Instruction::LONG_TO_FLOAT:
603 case Instruction::LONG_TO_DOUBLE:
604 case Instruction::FLOAT_TO_INT:
605 case Instruction::FLOAT_TO_LONG:
606 case Instruction::FLOAT_TO_DOUBLE:
607 case Instruction::DOUBLE_TO_INT:
608 case Instruction::DOUBLE_TO_LONG:
609 case Instruction::DOUBLE_TO_FLOAT:
buzbeee3acd072012-02-25 17:03:10 -0800610 genConversion(cUnit, mir);
611 break;
612
Elliott Hughesadb8c672012-03-06 16:49:32 -0800613 case Instruction::ADD_INT:
614 case Instruction::SUB_INT:
615 case Instruction::MUL_INT:
616 case Instruction::DIV_INT:
617 case Instruction::REM_INT:
618 case Instruction::AND_INT:
619 case Instruction::OR_INT:
620 case Instruction::XOR_INT:
621 case Instruction::SHL_INT:
622 case Instruction::SHR_INT:
623 case Instruction::USHR_INT:
624 case Instruction::ADD_INT_2ADDR:
625 case Instruction::SUB_INT_2ADDR:
626 case Instruction::MUL_INT_2ADDR:
627 case Instruction::DIV_INT_2ADDR:
628 case Instruction::REM_INT_2ADDR:
629 case Instruction::AND_INT_2ADDR:
630 case Instruction::OR_INT_2ADDR:
631 case Instruction::XOR_INT_2ADDR:
632 case Instruction::SHL_INT_2ADDR:
633 case Instruction::SHR_INT_2ADDR:
634 case Instruction::USHR_INT_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800635 genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
636 break;
637
Elliott Hughesadb8c672012-03-06 16:49:32 -0800638 case Instruction::ADD_LONG:
639 case Instruction::SUB_LONG:
640 case Instruction::MUL_LONG:
641 case Instruction::DIV_LONG:
642 case Instruction::REM_LONG:
643 case Instruction::AND_LONG:
644 case Instruction::OR_LONG:
645 case Instruction::XOR_LONG:
646 case Instruction::ADD_LONG_2ADDR:
647 case Instruction::SUB_LONG_2ADDR:
648 case Instruction::MUL_LONG_2ADDR:
649 case Instruction::DIV_LONG_2ADDR:
650 case Instruction::REM_LONG_2ADDR:
651 case Instruction::AND_LONG_2ADDR:
652 case Instruction::OR_LONG_2ADDR:
653 case Instruction::XOR_LONG_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800654 genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
655 break;
656
Elliott Hughesadb8c672012-03-06 16:49:32 -0800657 case Instruction::SHL_LONG:
658 case Instruction::SHR_LONG:
659 case Instruction::USHR_LONG:
660 case Instruction::SHL_LONG_2ADDR:
661 case Instruction::SHR_LONG_2ADDR:
662 case Instruction::USHR_LONG_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800663 genShiftOpLong(cUnit,mir, rlDest, rlSrc[0], rlSrc[1]);
664 break;
665
Elliott Hughesadb8c672012-03-06 16:49:32 -0800666 case Instruction::ADD_FLOAT:
667 case Instruction::SUB_FLOAT:
668 case Instruction::MUL_FLOAT:
669 case Instruction::DIV_FLOAT:
670 case Instruction::REM_FLOAT:
671 case Instruction::ADD_FLOAT_2ADDR:
672 case Instruction::SUB_FLOAT_2ADDR:
673 case Instruction::MUL_FLOAT_2ADDR:
674 case Instruction::DIV_FLOAT_2ADDR:
675 case Instruction::REM_FLOAT_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800676 genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
677 break;
678
Elliott Hughesadb8c672012-03-06 16:49:32 -0800679 case Instruction::ADD_DOUBLE:
680 case Instruction::SUB_DOUBLE:
681 case Instruction::MUL_DOUBLE:
682 case Instruction::DIV_DOUBLE:
683 case Instruction::REM_DOUBLE:
684 case Instruction::ADD_DOUBLE_2ADDR:
685 case Instruction::SUB_DOUBLE_2ADDR:
686 case Instruction::MUL_DOUBLE_2ADDR:
687 case Instruction::DIV_DOUBLE_2ADDR:
688 case Instruction::REM_DOUBLE_2ADDR:
buzbeee3acd072012-02-25 17:03:10 -0800689 genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
690 break;
691
Elliott Hughesadb8c672012-03-06 16:49:32 -0800692 case Instruction::RSUB_INT:
693 case Instruction::ADD_INT_LIT16:
694 case Instruction::MUL_INT_LIT16:
695 case Instruction::DIV_INT_LIT16:
696 case Instruction::REM_INT_LIT16:
697 case Instruction::AND_INT_LIT16:
698 case Instruction::OR_INT_LIT16:
699 case Instruction::XOR_INT_LIT16:
700 case Instruction::ADD_INT_LIT8:
701 case Instruction::RSUB_INT_LIT8:
702 case Instruction::MUL_INT_LIT8:
703 case Instruction::DIV_INT_LIT8:
704 case Instruction::REM_INT_LIT8:
705 case Instruction::AND_INT_LIT8:
706 case Instruction::OR_INT_LIT8:
707 case Instruction::XOR_INT_LIT8:
708 case Instruction::SHL_INT_LIT8:
709 case Instruction::SHR_INT_LIT8:
710 case Instruction::USHR_INT_LIT8:
buzbeee3acd072012-02-25 17:03:10 -0800711 genArithOpIntLit(cUnit, mir, rlDest, rlSrc[0], mir->dalvikInsn.vC);
712 break;
713
714 default:
715 res = true;
716 }
717 return res;
718}
719
buzbee31a4a6f2012-02-28 15:36:15 -0800720const char* extendedMIROpNames[kMirOpLast - kMirOpFirst] = {
buzbeee3acd072012-02-25 17:03:10 -0800721 "kMirOpPhi",
722 "kMirOpNullNRangeUpCheck",
723 "kMirOpNullNRangeDownCheck",
724 "kMirOpLowerBound",
buzbeee1965672012-03-11 18:39:19 -0700725 "kMirOpCopy",
buzbeee3acd072012-02-25 17:03:10 -0800726};
727
728/* Extended MIR instructions like PHI */
buzbee31a4a6f2012-02-28 15:36:15 -0800729void handleExtendedMethodMIR(CompilationUnit* cUnit, MIR* mir)
buzbeee3acd072012-02-25 17:03:10 -0800730{
731 int opOffset = mir->dalvikInsn.opcode - kMirOpFirst;
732 char* msg = NULL;
733 if (cUnit->printMe) {
734 msg = (char*)oatNew(cUnit, strlen(extendedMIROpNames[opOffset]) + 1,
735 false, kAllocDebugInfo);
736 strcpy(msg, extendedMIROpNames[opOffset]);
737 }
buzbee31a4a6f2012-02-28 15:36:15 -0800738 LIR* op = newLIR1(cUnit, kPseudoExtended, (int) msg);
buzbeee3acd072012-02-25 17:03:10 -0800739
740 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
741 case kMirOpPhi: {
742 char* ssaString = NULL;
743 if (cUnit->printMe) {
744 ssaString = oatGetSSAString(cUnit, mir->ssaRep);
745 }
746 op->flags.isNop = true;
buzbee31a4a6f2012-02-28 15:36:15 -0800747 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
buzbeee3acd072012-02-25 17:03:10 -0800748 break;
749 }
buzbeee1965672012-03-11 18:39:19 -0700750 case kMirOpCopy:
751 UNIMPLEMENTED(FATAL) << "Need kMirOpCopy";
752 break;
buzbeee3acd072012-02-25 17:03:10 -0800753 default:
754 break;
755 }
756}
757
758/* Handle the content in each basic block */
buzbee31a4a6f2012-02-28 15:36:15 -0800759bool methodBlockCodeGen(CompilationUnit* cUnit, BasicBlock* bb)
buzbeee3acd072012-02-25 17:03:10 -0800760{
761 MIR* mir;
buzbee31a4a6f2012-02-28 15:36:15 -0800762 LIR* labelList = (LIR*) cUnit->blockLabelList;
buzbeee3acd072012-02-25 17:03:10 -0800763 int blockId = bb->id;
764
765 cUnit->curBlock = bb;
766 labelList[blockId].operands[0] = bb->startOffset;
767
768 /* Insert the block label */
buzbee31a4a6f2012-02-28 15:36:15 -0800769 labelList[blockId].opcode = kPseudoNormalBlockLabel;
buzbeee3acd072012-02-25 17:03:10 -0800770 oatAppendLIR(cUnit, (LIR*) &labelList[blockId]);
771
buzbeee1965672012-03-11 18:39:19 -0700772 /* Free temp registers and reset redundant store tracking */
buzbeee3acd072012-02-25 17:03:10 -0800773 oatResetRegPool(cUnit);
buzbeee3acd072012-02-25 17:03:10 -0800774 oatResetDefTracking(cUnit);
775
buzbeee1965672012-03-11 18:39:19 -0700776 /*
777 * If control reached us from our immediate predecessor via
778 * fallthrough and we have no other incoming arcs we can
779 * reuse existing liveness. Otherwise, reset.
780 */
781 if (!bb->fallThroughTarget || bb->predecessors->numUsed != 1) {
782 oatClobberAllRegs(cUnit);
783 }
784
buzbee31a4a6f2012-02-28 15:36:15 -0800785 LIR* headLIR = NULL;
buzbeee3acd072012-02-25 17:03:10 -0800786
787 if (bb->blockType == kEntryBlock) {
788 genEntrySequence(cUnit, bb);
789 } else if (bb->blockType == kExitBlock) {
790 genExitSequence(cUnit, bb);
791 }
792
793 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
794
795 oatResetRegPool(cUnit);
796 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
797 oatClobberAllRegs(cUnit);
798 }
799
800 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
801 oatResetDefTracking(cUnit);
802 }
803
buzbee3d661942012-03-14 17:37:27 -0700804#ifndef NDEBUG
805 /* Reset temp tracking sanity check */
806 cUnit->liveSReg = INVALID_SREG;
807#endif
808
buzbeee3acd072012-02-25 17:03:10 -0800809 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
810 handleExtendedMethodMIR(cUnit, mir);
811 continue;
812 }
813
814 cUnit->currentDalvikOffset = mir->offset;
815
Elliott Hughesadb8c672012-03-06 16:49:32 -0800816 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
817 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
buzbeee3acd072012-02-25 17:03:10 -0800818
buzbee31a4a6f2012-02-28 15:36:15 -0800819 LIR* boundaryLIR;
buzbeee3acd072012-02-25 17:03:10 -0800820
821 /* Mark the beginning of a Dalvik instruction for line tracking */
822 char* instStr = cUnit->printMe ?
Elliott Hughesadb8c672012-03-06 16:49:32 -0800823 oatGetDalvikDisassembly(cUnit, mir->dalvikInsn, "") : NULL;
buzbee31a4a6f2012-02-28 15:36:15 -0800824 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
buzbeee3acd072012-02-25 17:03:10 -0800825 (intptr_t) instStr);
826 cUnit->boundaryMap.insert(std::make_pair(mir->offset,
827 (LIR*)boundaryLIR));
828 /* Remember the first LIR for this block */
829 if (headLIR == NULL) {
830 headLIR = boundaryLIR;
831 /* Set the first boundaryLIR as a scheduling barrier */
832 headLIR->defMask = ENCODE_ALL;
833 }
834
835 /* If we're compiling for the debugger, generate an update callout */
836 if (cUnit->genDebugger) {
837 genDebuggerUpdate(cUnit, mir->offset);
838 }
839
840 /* Don't generate the SSA annotation unless verbose mode is on */
841 if (cUnit->printMe && mir->ssaRep) {
842 char* ssaString = oatGetSSAString(cUnit, mir->ssaRep);
buzbee31a4a6f2012-02-28 15:36:15 -0800843 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
buzbeee3acd072012-02-25 17:03:10 -0800844 }
845
846 bool notHandled = compileDalvikInstruction(cUnit, mir, bb, labelList);
buzbeee3acd072012-02-25 17:03:10 -0800847 if (notHandled) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800848 LOG(FATAL) << StringPrintf("%#06x: Opcode %#x (%s) / Fmt %d not handled",
849 mir->offset, dalvikOpcode, Instruction::Name(dalvikOpcode), dalvikFormat);
850
buzbeee3acd072012-02-25 17:03:10 -0800851 }
852 }
853
854 if (headLIR) {
855 /*
856 * Eliminate redundant loads/stores and delay stores into later
857 * slots
858 */
859 oatApplyLocalOptimizations(cUnit, (LIR*) headLIR,
860 cUnit->lastLIRInsn);
861
862 /*
863 * Generate an unconditional branch to the fallthrough block.
864 */
865 if (bb->fallThrough) {
buzbee82488f52012-03-02 08:20:26 -0800866 opUnconditionalBranch(cUnit,
867 &labelList[bb->fallThrough->id]);
buzbeee3acd072012-02-25 17:03:10 -0800868 }
869 }
870 return false;
871}
872
873void oatMethodMIR2LIR(CompilationUnit* cUnit)
874{
875 /* Used to hold the labels of each block */
876 cUnit->blockLabelList =
buzbee31a4a6f2012-02-28 15:36:15 -0800877 (void *) oatNew(cUnit, sizeof(LIR) * cUnit->numBlocks, true,
buzbeee3acd072012-02-25 17:03:10 -0800878 kAllocLIR);
879
880 oatDataFlowAnalysisDispatcher(cUnit, methodBlockCodeGen,
881 kPreOrderDFSTraversal, false /* Iterative */);
882 handleSuspendLaunchpads(cUnit);
883
884 handleThrowLaunchpads(cUnit);
885
buzbee86a4bce2012-03-06 18:15:00 -0800886 if (!(cUnit->disableOpt & (1 << kSafeOptimizations))) {
887 removeRedundantBranches(cUnit);
888 }
buzbeee3acd072012-02-25 17:03:10 -0800889}
890
891/* Needed by the ld/st optmizatons */
buzbee31a4a6f2012-02-28 15:36:15 -0800892LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
buzbeee3acd072012-02-25 17:03:10 -0800893{
buzbee82488f52012-03-02 08:20:26 -0800894 return opRegCopyNoInsert(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -0800895}
896
897/* Needed by the register allocator */
898void oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
899{
buzbee82488f52012-03-02 08:20:26 -0800900 opRegCopy(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -0800901}
902
903/* Needed by the register allocator */
904void oatRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
905 int srcLo, int srcHi)
906{
buzbee82488f52012-03-02 08:20:26 -0800907 opRegCopyWide(cUnit, destLo, destHi, srcLo, srcHi);
buzbeee3acd072012-02-25 17:03:10 -0800908}
909
910void oatFlushRegImpl(CompilationUnit* cUnit, int rBase,
911 int displacement, int rSrc, OpSize size)
912{
913 storeBaseDisp(cUnit, rBase, displacement, rSrc, size);
914}
915
916void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase,
917 int displacement, int rSrcLo, int rSrcHi)
918{
919 storeBaseDispWide(cUnit, rBase, displacement, rSrcLo, rSrcHi);
920}
921
922} // namespace art