blob: 3808a355f21595e02b39668cb2dd17a74e2519aa [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
buzbee1bc37c62012-11-20 13:35:41 -080019#include "../compiler_internals.h"
buzbeeeaf09bc2012-11-15 14:51:41 -080020#include "local_optimizations.h"
buzbee1bc37c62012-11-20 13:35:41 -080021#include "codegen_util.h"
22#include "ralloc_util.h"
buzbeeeaf09bc2012-11-15 14:51:41 -080023
buzbeee3acd072012-02-25 17:03:10 -080024namespace art {
25
buzbee1bc37c62012-11-20 13:35:41 -080026// TODO: unify badLoc
buzbee2cfc6392012-05-07 14:51:40 -070027const RegLocation badLoc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0,
28 INVALID_REG, INVALID_REG, INVALID_SREG,
29 INVALID_SREG};
buzbeee3acd072012-02-25 17:03:10 -080030
31/* Mark register usage state and return long retloc */
buzbee52a77fc2012-11-20 19:50:46 -080032RegLocation GetReturnWide(CompilationUnit* cUnit, bool isDouble)
buzbeee3acd072012-02-25 17:03:10 -080033{
buzbee52a77fc2012-11-20 19:50:46 -080034 RegLocation gpr_res = LocCReturnWide();
35 RegLocation fpr_res = LocCReturnDouble();
Bill Buzbeea114add2012-05-03 15:00:40 -070036 RegLocation res = isDouble ? fpr_res : gpr_res;
buzbee52a77fc2012-11-20 19:50:46 -080037 Clobber(cUnit, res.lowReg);
38 Clobber(cUnit, res.highReg);
39 LockTemp(cUnit, res.lowReg);
40 LockTemp(cUnit, res.highReg);
41 MarkPair(cUnit, res.lowReg, res.highReg);
Bill Buzbeea114add2012-05-03 15:00:40 -070042 return res;
buzbeee3acd072012-02-25 17:03:10 -080043}
44
buzbee52a77fc2012-11-20 19:50:46 -080045RegLocation GetReturn(CompilationUnit* cUnit, bool isFloat)
buzbeee3acd072012-02-25 17:03:10 -080046{
buzbee52a77fc2012-11-20 19:50:46 -080047 RegLocation gpr_res = LocCReturn();
48 RegLocation fpr_res = LocCReturnFloat();
Ian Rogersf7d9ad32012-03-13 18:45:39 -070049 RegLocation res = isFloat ? fpr_res : gpr_res;
buzbee52a77fc2012-11-20 19:50:46 -080050 Clobber(cUnit, res.lowReg);
Bill Buzbeea114add2012-05-03 15:00:40 -070051 if (cUnit->instructionSet == kMips) {
buzbee52a77fc2012-11-20 19:50:46 -080052 MarkInUse(cUnit, res.lowReg);
Bill Buzbeea114add2012-05-03 15:00:40 -070053 } else {
buzbee52a77fc2012-11-20 19:50:46 -080054 LockTemp(cUnit, res.lowReg);
Bill Buzbeea114add2012-05-03 15:00:40 -070055 }
56 return res;
buzbeee3acd072012-02-25 17:03:10 -080057}
58
buzbeee3acd072012-02-25 17:03:10 -080059/*
60 * Target-independent code generation. Use only high-level
61 * load/store utilities here, or target-dependent genXX() handlers
62 * when necessary.
63 */
buzbeeaad94382012-11-21 07:40:50 -080064static bool CompileDalvikInstruction(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
65 LIR* labelList)
buzbeee3acd072012-02-25 17:03:10 -080066{
Bill Buzbeea114add2012-05-03 15:00:40 -070067 bool res = false; // Assume success
68 RegLocation rlSrc[3];
69 RegLocation rlDest = badLoc;
70 RegLocation rlResult = badLoc;
71 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee408ad162012-06-06 16:45:18 -070072 int optFlags = mir->optimizationFlags;
buzbee408ad162012-06-06 16:45:18 -070073 uint32_t vB = mir->dalvikInsn.vB;
74 uint32_t vC = mir->dalvikInsn.vC;
buzbeee3acd072012-02-25 17:03:10 -080075
Bill Buzbeea114add2012-05-03 15:00:40 -070076 /* Prep Src and Dest locations */
77 int nextSreg = 0;
78 int nextLoc = 0;
79 int attrs = oatDataFlowAttributes[opcode];
80 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
81 if (attrs & DF_UA) {
buzbeebff24652012-05-06 16:22:05 -070082 if (attrs & DF_A_WIDE) {
buzbee52a77fc2012-11-20 19:50:46 -080083 rlSrc[nextLoc++] = GetSrcWide(cUnit, mir, nextSreg);
buzbeebff24652012-05-06 16:22:05 -070084 nextSreg+= 2;
85 } else {
buzbee52a77fc2012-11-20 19:50:46 -080086 rlSrc[nextLoc++] = GetSrc(cUnit, mir, nextSreg);
buzbeebff24652012-05-06 16:22:05 -070087 nextSreg++;
88 }
Bill Buzbeea114add2012-05-03 15:00:40 -070089 }
90 if (attrs & DF_UB) {
buzbeebff24652012-05-06 16:22:05 -070091 if (attrs & DF_B_WIDE) {
buzbee52a77fc2012-11-20 19:50:46 -080092 rlSrc[nextLoc++] = GetSrcWide(cUnit, mir, nextSreg);
buzbeebff24652012-05-06 16:22:05 -070093 nextSreg+= 2;
94 } else {
buzbee52a77fc2012-11-20 19:50:46 -080095 rlSrc[nextLoc++] = GetSrc(cUnit, mir, nextSreg);
buzbeebff24652012-05-06 16:22:05 -070096 nextSreg++;
97 }
Bill Buzbeea114add2012-05-03 15:00:40 -070098 }
99 if (attrs & DF_UC) {
buzbeebff24652012-05-06 16:22:05 -0700100 if (attrs & DF_C_WIDE) {
buzbee52a77fc2012-11-20 19:50:46 -0800101 rlSrc[nextLoc++] = GetSrcWide(cUnit, mir, nextSreg);
buzbeebff24652012-05-06 16:22:05 -0700102 } else {
buzbee52a77fc2012-11-20 19:50:46 -0800103 rlSrc[nextLoc++] = GetSrc(cUnit, mir, nextSreg);
buzbeebff24652012-05-06 16:22:05 -0700104 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700105 }
106 if (attrs & DF_DA) {
buzbeebff24652012-05-06 16:22:05 -0700107 if (attrs & DF_A_WIDE) {
buzbee52a77fc2012-11-20 19:50:46 -0800108 rlDest = GetDestWide(cUnit, mir);
buzbeebff24652012-05-06 16:22:05 -0700109 } else {
buzbee52a77fc2012-11-20 19:50:46 -0800110 rlDest = GetDest(cUnit, mir);
buzbeebff24652012-05-06 16:22:05 -0700111 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700112 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700113 switch (opcode) {
114 case Instruction::NOP:
115 break;
buzbeee3acd072012-02-25 17:03:10 -0800116
Ian Rogers474b6da2012-09-25 00:20:38 -0700117 case Instruction::MOVE_EXCEPTION:
buzbee52a77fc2012-11-20 19:50:46 -0800118 GenMoveException(cUnit, rlDest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700119 break;
Bill Buzbeea114add2012-05-03 15:00:40 -0700120 case Instruction::RETURN_VOID:
TDYa1274f2935e2012-06-22 06:25:03 -0700121 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee52a77fc2012-11-20 19:50:46 -0800122 GenSuspendTest(cUnit, optFlags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700123 }
124 break;
125
126 case Instruction::RETURN:
127 case Instruction::RETURN_OBJECT:
TDYa1274f2935e2012-06-22 06:25:03 -0700128 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee52a77fc2012-11-20 19:50:46 -0800129 GenSuspendTest(cUnit, optFlags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700130 }
buzbee52a77fc2012-11-20 19:50:46 -0800131 StoreValue(cUnit, GetReturn(cUnit, cUnit->shorty[0] == 'F'), rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700132 break;
133
134 case Instruction::RETURN_WIDE:
TDYa1274f2935e2012-06-22 06:25:03 -0700135 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee52a77fc2012-11-20 19:50:46 -0800136 GenSuspendTest(cUnit, optFlags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700137 }
buzbee52a77fc2012-11-20 19:50:46 -0800138 StoreValueWide(cUnit, GetReturnWide(cUnit,
Bill Buzbeea114add2012-05-03 15:00:40 -0700139 cUnit->shorty[0] == 'D'), rlSrc[0]);
140 break;
141
142 case Instruction::MOVE_RESULT_WIDE:
buzbee408ad162012-06-06 16:45:18 -0700143 if (optFlags & MIR_INLINED)
Bill Buzbeea114add2012-05-03 15:00:40 -0700144 break; // Nop - combined w/ previous invoke
buzbee52a77fc2012-11-20 19:50:46 -0800145 StoreValueWide(cUnit, rlDest, GetReturnWide(cUnit, rlDest.fp));
Bill Buzbeea114add2012-05-03 15:00:40 -0700146 break;
147
148 case Instruction::MOVE_RESULT:
149 case Instruction::MOVE_RESULT_OBJECT:
buzbee408ad162012-06-06 16:45:18 -0700150 if (optFlags & MIR_INLINED)
Bill Buzbeea114add2012-05-03 15:00:40 -0700151 break; // Nop - combined w/ previous invoke
buzbee52a77fc2012-11-20 19:50:46 -0800152 StoreValue(cUnit, rlDest, GetReturn(cUnit, rlDest.fp));
Bill Buzbeea114add2012-05-03 15:00:40 -0700153 break;
154
155 case Instruction::MOVE:
156 case Instruction::MOVE_OBJECT:
157 case Instruction::MOVE_16:
158 case Instruction::MOVE_OBJECT_16:
159 case Instruction::MOVE_FROM16:
160 case Instruction::MOVE_OBJECT_FROM16:
buzbee52a77fc2012-11-20 19:50:46 -0800161 StoreValue(cUnit, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700162 break;
163
164 case Instruction::MOVE_WIDE:
165 case Instruction::MOVE_WIDE_16:
166 case Instruction::MOVE_WIDE_FROM16:
buzbee52a77fc2012-11-20 19:50:46 -0800167 StoreValueWide(cUnit, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700168 break;
169
170 case Instruction::CONST:
171 case Instruction::CONST_4:
172 case Instruction::CONST_16:
buzbee52a77fc2012-11-20 19:50:46 -0800173 rlResult = EvalLoc(cUnit, rlDest, kAnyReg, true);
174 LoadConstantNoClobber(cUnit, rlResult.lowReg, vB);
175 StoreValue(cUnit, rlDest, rlResult);
Bill Buzbeea114add2012-05-03 15:00:40 -0700176 break;
177
178 case Instruction::CONST_HIGH16:
buzbee52a77fc2012-11-20 19:50:46 -0800179 rlResult = EvalLoc(cUnit, rlDest, kAnyReg, true);
180 LoadConstantNoClobber(cUnit, rlResult.lowReg, vB << 16);
181 StoreValue(cUnit, rlDest, rlResult);
Bill Buzbeea114add2012-05-03 15:00:40 -0700182 break;
183
184 case Instruction::CONST_WIDE_16:
185 case Instruction::CONST_WIDE_32:
buzbee52a77fc2012-11-20 19:50:46 -0800186 rlResult = EvalLoc(cUnit, rlDest, kAnyReg, true);
187 LoadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg, vB,
buzbee408ad162012-06-06 16:45:18 -0700188 (vB & 0x80000000) ? -1 : 0);
buzbee52a77fc2012-11-20 19:50:46 -0800189 StoreValueWide(cUnit, rlDest, rlResult);
Bill Buzbeea114add2012-05-03 15:00:40 -0700190 break;
191
192 case Instruction::CONST_WIDE:
buzbee52a77fc2012-11-20 19:50:46 -0800193 rlResult = EvalLoc(cUnit, rlDest, kAnyReg, true);
194 LoadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
Bill Buzbeea114add2012-05-03 15:00:40 -0700195 mir->dalvikInsn.vB_wide & 0xffffffff,
196 (mir->dalvikInsn.vB_wide >> 32) & 0xffffffff);
buzbee52a77fc2012-11-20 19:50:46 -0800197 StoreValueWide(cUnit, rlDest, rlResult);
Bill Buzbeea114add2012-05-03 15:00:40 -0700198 break;
199
200 case Instruction::CONST_WIDE_HIGH16:
buzbee52a77fc2012-11-20 19:50:46 -0800201 rlResult = EvalLoc(cUnit, rlDest, kAnyReg, true);
202 LoadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
buzbee408ad162012-06-06 16:45:18 -0700203 0, vB << 16);
buzbee52a77fc2012-11-20 19:50:46 -0800204 StoreValueWide(cUnit, rlDest, rlResult);
Bill Buzbeea114add2012-05-03 15:00:40 -0700205 break;
206
207 case Instruction::MONITOR_ENTER:
buzbee52a77fc2012-11-20 19:50:46 -0800208 GenMonitorEnter(cUnit, optFlags, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700209 break;
210
211 case Instruction::MONITOR_EXIT:
buzbee52a77fc2012-11-20 19:50:46 -0800212 GenMonitorExit(cUnit, optFlags, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700213 break;
214
215 case Instruction::CHECK_CAST:
buzbee52a77fc2012-11-20 19:50:46 -0800216 GenCheckCast(cUnit, vB, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700217 break;
218
219 case Instruction::INSTANCE_OF:
buzbee52a77fc2012-11-20 19:50:46 -0800220 GenInstanceof(cUnit, vC, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700221 break;
222
223 case Instruction::NEW_INSTANCE:
buzbee52a77fc2012-11-20 19:50:46 -0800224 GenNewInstance(cUnit, vB, rlDest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700225 break;
226
227 case Instruction::THROW:
buzbee52a77fc2012-11-20 19:50:46 -0800228 GenThrow(cUnit, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700229 break;
230
Bill Buzbeea114add2012-05-03 15:00:40 -0700231 case Instruction::ARRAY_LENGTH:
232 int lenOffset;
233 lenOffset = Array::LengthOffset().Int32Value();
buzbee52a77fc2012-11-20 19:50:46 -0800234 rlSrc[0] = LoadValue(cUnit, rlSrc[0], kCoreReg);
235 GenNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, optFlags);
236 rlResult = EvalLoc(cUnit, rlDest, kCoreReg, true);
237 LoadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset, rlResult.lowReg);
238 StoreValue(cUnit, rlDest, rlResult);
Bill Buzbeea114add2012-05-03 15:00:40 -0700239 break;
240
241 case Instruction::CONST_STRING:
242 case Instruction::CONST_STRING_JUMBO:
buzbee52a77fc2012-11-20 19:50:46 -0800243 GenConstString(cUnit, vB, rlDest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700244 break;
245
246 case Instruction::CONST_CLASS:
buzbee52a77fc2012-11-20 19:50:46 -0800247 GenConstClass(cUnit, vB, rlDest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700248 break;
249
250 case Instruction::FILL_ARRAY_DATA:
buzbee52a77fc2012-11-20 19:50:46 -0800251 GenFillArrayData(cUnit, vB, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700252 break;
253
254 case Instruction::FILLED_NEW_ARRAY:
buzbee52a77fc2012-11-20 19:50:46 -0800255 GenFilledNewArray(cUnit, NewMemCallInfo(cUnit, bb, mir, kStatic,
buzbee3b3dbdd2012-06-13 13:39:34 -0700256 false /* not range */));
Bill Buzbeea114add2012-05-03 15:00:40 -0700257 break;
258
259 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbee52a77fc2012-11-20 19:50:46 -0800260 GenFilledNewArray(cUnit, NewMemCallInfo(cUnit, bb, mir, kStatic,
buzbee3b3dbdd2012-06-13 13:39:34 -0700261 true /* range */));
Bill Buzbeea114add2012-05-03 15:00:40 -0700262 break;
263
264 case Instruction::NEW_ARRAY:
buzbee52a77fc2012-11-20 19:50:46 -0800265 GenNewArray(cUnit, vC, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700266 break;
267
268 case Instruction::GOTO:
269 case Instruction::GOTO_16:
270 case Instruction::GOTO_32:
271 if (bb->taken->startOffset <= mir->offset) {
buzbee52a77fc2012-11-20 19:50:46 -0800272 GenSuspendTestAndBranch(cUnit, optFlags, &labelList[bb->taken->id]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700273 } else {
buzbee52a77fc2012-11-20 19:50:46 -0800274 OpUnconditionalBranch(cUnit, &labelList[bb->taken->id]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700275 }
276 break;
277
278 case Instruction::PACKED_SWITCH:
buzbee52a77fc2012-11-20 19:50:46 -0800279 GenPackedSwitch(cUnit, vB, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700280 break;
281
282 case Instruction::SPARSE_SWITCH:
buzbee52a77fc2012-11-20 19:50:46 -0800283 GenSparseSwitch(cUnit, vB, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700284 break;
285
286 case Instruction::CMPL_FLOAT:
287 case Instruction::CMPG_FLOAT:
288 case Instruction::CMPL_DOUBLE:
289 case Instruction::CMPG_DOUBLE:
buzbee52a77fc2012-11-20 19:50:46 -0800290 res = GenCmpFP(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700291 break;
292
293 case Instruction::CMP_LONG:
buzbee52a77fc2012-11-20 19:50:46 -0800294 GenCmpLong(cUnit, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700295 break;
296
297 case Instruction::IF_EQ:
298 case Instruction::IF_NE:
299 case Instruction::IF_LT:
300 case Instruction::IF_GE:
301 case Instruction::IF_GT:
302 case Instruction::IF_LE: {
buzbee3b3dbdd2012-06-13 13:39:34 -0700303 LIR* taken = &labelList[bb->taken->id];
304 LIR* fallThrough = &labelList[bb->fallThrough->id];
Bill Buzbeea114add2012-05-03 15:00:40 -0700305 bool backwardBranch;
306 backwardBranch = (bb->taken->startOffset <= mir->offset);
307 if (backwardBranch) {
buzbee52a77fc2012-11-20 19:50:46 -0800308 GenSuspendTest(cUnit, optFlags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700309 }
buzbee52a77fc2012-11-20 19:50:46 -0800310 GenCompareAndBranch(cUnit, opcode, rlSrc[0], rlSrc[1], taken,
buzbee3b3dbdd2012-06-13 13:39:34 -0700311 fallThrough);
Bill Buzbeea114add2012-05-03 15:00:40 -0700312 break;
313 }
314
315 case Instruction::IF_EQZ:
316 case Instruction::IF_NEZ:
317 case Instruction::IF_LTZ:
318 case Instruction::IF_GEZ:
319 case Instruction::IF_GTZ:
320 case Instruction::IF_LEZ: {
buzbee3b3dbdd2012-06-13 13:39:34 -0700321 LIR* taken = &labelList[bb->taken->id];
322 LIR* fallThrough = &labelList[bb->fallThrough->id];
Bill Buzbeea114add2012-05-03 15:00:40 -0700323 bool backwardBranch;
324 backwardBranch = (bb->taken->startOffset <= mir->offset);
325 if (backwardBranch) {
buzbee52a77fc2012-11-20 19:50:46 -0800326 GenSuspendTest(cUnit, optFlags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700327 }
buzbee52a77fc2012-11-20 19:50:46 -0800328 GenCompareZeroAndBranch(cUnit, opcode, rlSrc[0], taken, fallThrough);
Bill Buzbeea114add2012-05-03 15:00:40 -0700329 break;
330 }
331
332 case Instruction::AGET_WIDE:
buzbee52a77fc2012-11-20 19:50:46 -0800333 GenArrayGet(cUnit, optFlags, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
Bill Buzbeea114add2012-05-03 15:00:40 -0700334 break;
335 case Instruction::AGET:
336 case Instruction::AGET_OBJECT:
buzbee52a77fc2012-11-20 19:50:46 -0800337 GenArrayGet(cUnit, optFlags, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700338 break;
339 case Instruction::AGET_BOOLEAN:
buzbee52a77fc2012-11-20 19:50:46 -0800340 GenArrayGet(cUnit, optFlags, kUnsignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700341 break;
342 case Instruction::AGET_BYTE:
buzbee52a77fc2012-11-20 19:50:46 -0800343 GenArrayGet(cUnit, optFlags, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700344 break;
345 case Instruction::AGET_CHAR:
buzbee52a77fc2012-11-20 19:50:46 -0800346 GenArrayGet(cUnit, optFlags, kUnsignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700347 break;
348 case Instruction::AGET_SHORT:
buzbee52a77fc2012-11-20 19:50:46 -0800349 GenArrayGet(cUnit, optFlags, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700350 break;
351 case Instruction::APUT_WIDE:
buzbee52a77fc2012-11-20 19:50:46 -0800352 GenArrayPut(cUnit, optFlags, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
Bill Buzbeea114add2012-05-03 15:00:40 -0700353 break;
354 case Instruction::APUT:
buzbee52a77fc2012-11-20 19:50:46 -0800355 GenArrayPut(cUnit, optFlags, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700356 break;
357 case Instruction::APUT_OBJECT:
buzbee52a77fc2012-11-20 19:50:46 -0800358 GenArrayObjPut(cUnit, optFlags, rlSrc[1], rlSrc[2], rlSrc[0], 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700359 break;
360 case Instruction::APUT_SHORT:
361 case Instruction::APUT_CHAR:
buzbee52a77fc2012-11-20 19:50:46 -0800362 GenArrayPut(cUnit, optFlags, kUnsignedHalf, rlSrc[1], rlSrc[2], rlSrc[0], 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700363 break;
364 case Instruction::APUT_BYTE:
365 case Instruction::APUT_BOOLEAN:
buzbee52a77fc2012-11-20 19:50:46 -0800366 GenArrayPut(cUnit, optFlags, kUnsignedByte, rlSrc[1], rlSrc[2],
Bill Buzbeea114add2012-05-03 15:00:40 -0700367 rlSrc[0], 0);
368 break;
369
370 case Instruction::IGET_OBJECT:
371 //case Instruction::IGET_OBJECT_VOLATILE:
buzbee52a77fc2012-11-20 19:50:46 -0800372 GenIGet(cUnit, vC, optFlags, kWord, rlDest, rlSrc[0], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700373 break;
374
375 case Instruction::IGET_WIDE:
376 //case Instruction::IGET_WIDE_VOLATILE:
buzbee52a77fc2012-11-20 19:50:46 -0800377 GenIGet(cUnit, vC, optFlags, kLong, rlDest, rlSrc[0], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700378 break;
379
380 case Instruction::IGET:
381 //case Instruction::IGET_VOLATILE:
buzbee52a77fc2012-11-20 19:50:46 -0800382 GenIGet(cUnit, vC, optFlags, kWord, rlDest, rlSrc[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700383 break;
384
385 case Instruction::IGET_CHAR:
buzbee52a77fc2012-11-20 19:50:46 -0800386 GenIGet(cUnit, vC, optFlags, kUnsignedHalf, rlDest, rlSrc[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700387 break;
388
389 case Instruction::IGET_SHORT:
buzbee52a77fc2012-11-20 19:50:46 -0800390 GenIGet(cUnit, vC, optFlags, kSignedHalf, rlDest, rlSrc[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700391 break;
392
393 case Instruction::IGET_BOOLEAN:
394 case Instruction::IGET_BYTE:
buzbee52a77fc2012-11-20 19:50:46 -0800395 GenIGet(cUnit, vC, optFlags, kUnsignedByte, rlDest, rlSrc[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700396 break;
397
398 case Instruction::IPUT_WIDE:
399 //case Instruction::IPUT_WIDE_VOLATILE:
buzbee52a77fc2012-11-20 19:50:46 -0800400 GenIPut(cUnit, vC, optFlags, kLong, rlSrc[0], rlSrc[1], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700401 break;
402
403 case Instruction::IPUT_OBJECT:
404 //case Instruction::IPUT_OBJECT_VOLATILE:
buzbee52a77fc2012-11-20 19:50:46 -0800405 GenIPut(cUnit, vC, optFlags, kWord, rlSrc[0], rlSrc[1], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700406 break;
407
408 case Instruction::IPUT:
409 //case Instruction::IPUT_VOLATILE:
buzbee52a77fc2012-11-20 19:50:46 -0800410 GenIPut(cUnit, vC, optFlags, kWord, rlSrc[0], rlSrc[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700411 break;
412
413 case Instruction::IPUT_BOOLEAN:
414 case Instruction::IPUT_BYTE:
buzbee52a77fc2012-11-20 19:50:46 -0800415 GenIPut(cUnit, vC, optFlags, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700416 break;
417
418 case Instruction::IPUT_CHAR:
buzbee52a77fc2012-11-20 19:50:46 -0800419 GenIPut(cUnit, vC, optFlags, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700420 break;
421
422 case Instruction::IPUT_SHORT:
buzbee52a77fc2012-11-20 19:50:46 -0800423 GenIPut(cUnit, vC, optFlags, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700424 break;
425
426 case Instruction::SGET_OBJECT:
buzbee52a77fc2012-11-20 19:50:46 -0800427 GenSget(cUnit, vB, rlDest, false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700428 break;
429 case Instruction::SGET:
430 case Instruction::SGET_BOOLEAN:
431 case Instruction::SGET_BYTE:
432 case Instruction::SGET_CHAR:
433 case Instruction::SGET_SHORT:
buzbee52a77fc2012-11-20 19:50:46 -0800434 GenSget(cUnit, vB, rlDest, false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700435 break;
436
437 case Instruction::SGET_WIDE:
buzbee52a77fc2012-11-20 19:50:46 -0800438 GenSget(cUnit, vB, rlDest, true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700439 break;
440
441 case Instruction::SPUT_OBJECT:
buzbee52a77fc2012-11-20 19:50:46 -0800442 GenSput(cUnit, vB, rlSrc[0], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700443 break;
444
445 case Instruction::SPUT:
446 case Instruction::SPUT_BOOLEAN:
447 case Instruction::SPUT_BYTE:
448 case Instruction::SPUT_CHAR:
449 case Instruction::SPUT_SHORT:
buzbee52a77fc2012-11-20 19:50:46 -0800450 GenSput(cUnit, vB, rlSrc[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700451 break;
452
453 case Instruction::SPUT_WIDE:
buzbee52a77fc2012-11-20 19:50:46 -0800454 GenSput(cUnit, vB, rlSrc[0], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700455 break;
456
457 case Instruction::INVOKE_STATIC_RANGE:
buzbee52a77fc2012-11-20 19:50:46 -0800458 GenInvoke(cUnit, NewMemCallInfo(cUnit, bb, mir, kStatic, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700459 break;
460 case Instruction::INVOKE_STATIC:
buzbee52a77fc2012-11-20 19:50:46 -0800461 GenInvoke(cUnit, NewMemCallInfo(cUnit, bb, mir, kStatic, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700462 break;
463
464 case Instruction::INVOKE_DIRECT:
buzbee52a77fc2012-11-20 19:50:46 -0800465 GenInvoke(cUnit, NewMemCallInfo(cUnit, bb, mir, kDirect, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700466 break;
467 case Instruction::INVOKE_DIRECT_RANGE:
buzbee52a77fc2012-11-20 19:50:46 -0800468 GenInvoke(cUnit, NewMemCallInfo(cUnit, bb, mir, kDirect, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700469 break;
470
471 case Instruction::INVOKE_VIRTUAL:
buzbee52a77fc2012-11-20 19:50:46 -0800472 GenInvoke(cUnit, NewMemCallInfo(cUnit, bb, mir, kVirtual, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700473 break;
474 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee52a77fc2012-11-20 19:50:46 -0800475 GenInvoke(cUnit, NewMemCallInfo(cUnit, bb, mir, kVirtual, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700476 break;
477
478 case Instruction::INVOKE_SUPER:
buzbee52a77fc2012-11-20 19:50:46 -0800479 GenInvoke(cUnit, NewMemCallInfo(cUnit, bb, mir, kSuper, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700480 break;
481 case Instruction::INVOKE_SUPER_RANGE:
buzbee52a77fc2012-11-20 19:50:46 -0800482 GenInvoke(cUnit, NewMemCallInfo(cUnit, bb, mir, kSuper, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700483 break;
484
485 case Instruction::INVOKE_INTERFACE:
buzbee52a77fc2012-11-20 19:50:46 -0800486 GenInvoke(cUnit, NewMemCallInfo(cUnit, bb, mir, kInterface, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700487 break;
488 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee52a77fc2012-11-20 19:50:46 -0800489 GenInvoke(cUnit, NewMemCallInfo(cUnit, bb, mir, kInterface, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700490 break;
491
492 case Instruction::NEG_INT:
493 case Instruction::NOT_INT:
buzbee52a77fc2012-11-20 19:50:46 -0800494 res = GenArithOpInt(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700495 break;
496
497 case Instruction::NEG_LONG:
498 case Instruction::NOT_LONG:
buzbee52a77fc2012-11-20 19:50:46 -0800499 res = GenArithOpLong(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700500 break;
501
502 case Instruction::NEG_FLOAT:
buzbee52a77fc2012-11-20 19:50:46 -0800503 res = GenArithOpFloat(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700504 break;
505
506 case Instruction::NEG_DOUBLE:
buzbee52a77fc2012-11-20 19:50:46 -0800507 res = GenArithOpDouble(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700508 break;
509
510 case Instruction::INT_TO_LONG:
buzbee52a77fc2012-11-20 19:50:46 -0800511 GenIntToLong(cUnit, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700512 break;
513
514 case Instruction::LONG_TO_INT:
buzbee52a77fc2012-11-20 19:50:46 -0800515 rlSrc[0] = UpdateLocWide(cUnit, rlSrc[0]);
516 rlSrc[0] = WideToNarrow(cUnit, rlSrc[0]);
517 StoreValue(cUnit, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700518 break;
519
520 case Instruction::INT_TO_BYTE:
521 case Instruction::INT_TO_SHORT:
522 case Instruction::INT_TO_CHAR:
buzbee52a77fc2012-11-20 19:50:46 -0800523 GenIntNarrowing(cUnit, opcode, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700524 break;
525
526 case Instruction::INT_TO_FLOAT:
527 case Instruction::INT_TO_DOUBLE:
528 case Instruction::LONG_TO_FLOAT:
529 case Instruction::LONG_TO_DOUBLE:
530 case Instruction::FLOAT_TO_INT:
531 case Instruction::FLOAT_TO_LONG:
532 case Instruction::FLOAT_TO_DOUBLE:
533 case Instruction::DOUBLE_TO_INT:
534 case Instruction::DOUBLE_TO_LONG:
535 case Instruction::DOUBLE_TO_FLOAT:
buzbee52a77fc2012-11-20 19:50:46 -0800536 GenConversion(cUnit, opcode, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700537 break;
538
539 case Instruction::ADD_INT:
540 case Instruction::SUB_INT:
541 case Instruction::MUL_INT:
542 case Instruction::DIV_INT:
543 case Instruction::REM_INT:
544 case Instruction::AND_INT:
545 case Instruction::OR_INT:
546 case Instruction::XOR_INT:
547 case Instruction::SHL_INT:
548 case Instruction::SHR_INT:
549 case Instruction::USHR_INT:
550 case Instruction::ADD_INT_2ADDR:
551 case Instruction::SUB_INT_2ADDR:
552 case Instruction::MUL_INT_2ADDR:
553 case Instruction::DIV_INT_2ADDR:
554 case Instruction::REM_INT_2ADDR:
555 case Instruction::AND_INT_2ADDR:
556 case Instruction::OR_INT_2ADDR:
557 case Instruction::XOR_INT_2ADDR:
558 case Instruction::SHL_INT_2ADDR:
559 case Instruction::SHR_INT_2ADDR:
560 case Instruction::USHR_INT_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -0800561 GenArithOpInt(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700562 break;
563
564 case Instruction::ADD_LONG:
565 case Instruction::SUB_LONG:
566 case Instruction::MUL_LONG:
567 case Instruction::DIV_LONG:
568 case Instruction::REM_LONG:
569 case Instruction::AND_LONG:
570 case Instruction::OR_LONG:
571 case Instruction::XOR_LONG:
572 case Instruction::ADD_LONG_2ADDR:
573 case Instruction::SUB_LONG_2ADDR:
574 case Instruction::MUL_LONG_2ADDR:
575 case Instruction::DIV_LONG_2ADDR:
576 case Instruction::REM_LONG_2ADDR:
577 case Instruction::AND_LONG_2ADDR:
578 case Instruction::OR_LONG_2ADDR:
579 case Instruction::XOR_LONG_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -0800580 GenArithOpLong(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700581 break;
582
583 case Instruction::SHL_LONG:
584 case Instruction::SHR_LONG:
585 case Instruction::USHR_LONG:
586 case Instruction::SHL_LONG_2ADDR:
587 case Instruction::SHR_LONG_2ADDR:
588 case Instruction::USHR_LONG_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -0800589 GenShiftOpLong(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700590 break;
591
592 case Instruction::ADD_FLOAT:
593 case Instruction::SUB_FLOAT:
594 case Instruction::MUL_FLOAT:
595 case Instruction::DIV_FLOAT:
596 case Instruction::REM_FLOAT:
597 case Instruction::ADD_FLOAT_2ADDR:
598 case Instruction::SUB_FLOAT_2ADDR:
599 case Instruction::MUL_FLOAT_2ADDR:
600 case Instruction::DIV_FLOAT_2ADDR:
601 case Instruction::REM_FLOAT_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -0800602 GenArithOpFloat(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700603 break;
604
605 case Instruction::ADD_DOUBLE:
606 case Instruction::SUB_DOUBLE:
607 case Instruction::MUL_DOUBLE:
608 case Instruction::DIV_DOUBLE:
609 case Instruction::REM_DOUBLE:
610 case Instruction::ADD_DOUBLE_2ADDR:
611 case Instruction::SUB_DOUBLE_2ADDR:
612 case Instruction::MUL_DOUBLE_2ADDR:
613 case Instruction::DIV_DOUBLE_2ADDR:
614 case Instruction::REM_DOUBLE_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -0800615 GenArithOpDouble(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700616 break;
617
618 case Instruction::RSUB_INT:
619 case Instruction::ADD_INT_LIT16:
620 case Instruction::MUL_INT_LIT16:
621 case Instruction::DIV_INT_LIT16:
622 case Instruction::REM_INT_LIT16:
623 case Instruction::AND_INT_LIT16:
624 case Instruction::OR_INT_LIT16:
625 case Instruction::XOR_INT_LIT16:
626 case Instruction::ADD_INT_LIT8:
627 case Instruction::RSUB_INT_LIT8:
628 case Instruction::MUL_INT_LIT8:
629 case Instruction::DIV_INT_LIT8:
630 case Instruction::REM_INT_LIT8:
631 case Instruction::AND_INT_LIT8:
632 case Instruction::OR_INT_LIT8:
633 case Instruction::XOR_INT_LIT8:
634 case Instruction::SHL_INT_LIT8:
635 case Instruction::SHR_INT_LIT8:
636 case Instruction::USHR_INT_LIT8:
buzbee52a77fc2012-11-20 19:50:46 -0800637 GenArithOpIntLit(cUnit, opcode, rlDest, rlSrc[0], vC);
Bill Buzbeea114add2012-05-03 15:00:40 -0700638 break;
639
640 default:
641 res = true;
642 }
643 return res;
buzbeee3acd072012-02-25 17:03:10 -0800644}
645
buzbeee3acd072012-02-25 17:03:10 -0800646/* Extended MIR instructions like PHI */
buzbeeaad94382012-11-21 07:40:50 -0800647static void HandleExtendedMethodMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
buzbeee3acd072012-02-25 17:03:10 -0800648{
Bill Buzbeea114add2012-05-03 15:00:40 -0700649 int opOffset = mir->dalvikInsn.opcode - kMirOpFirst;
650 char* msg = NULL;
651 if (cUnit->printMe) {
buzbee52a77fc2012-11-20 19:50:46 -0800652 msg = static_cast<char*>(NewMem(cUnit, strlen(extendedMIROpNames[opOffset]) + 1,
buzbeecbd6d442012-11-17 14:11:25 -0800653 false, kAllocDebugInfo));
Bill Buzbeea114add2012-05-03 15:00:40 -0700654 strcpy(msg, extendedMIROpNames[opOffset]);
655 }
buzbee52a77fc2012-11-20 19:50:46 -0800656 LIR* op = NewLIR1(cUnit, kPseudoExtended, reinterpret_cast<uintptr_t>(msg));
buzbeee3acd072012-02-25 17:03:10 -0800657
buzbeecbd6d442012-11-17 14:11:25 -0800658 switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700659 case kMirOpPhi: {
660 char* ssaString = NULL;
661 if (cUnit->printMe) {
buzbee52a77fc2012-11-20 19:50:46 -0800662 ssaString = GetSSAString(cUnit, mir->ssaRep);
Bill Buzbeea114add2012-05-03 15:00:40 -0700663 }
664 op->flags.isNop = true;
buzbee52a77fc2012-11-20 19:50:46 -0800665 NewLIR1(cUnit, kPseudoSSARep, reinterpret_cast<uintptr_t>(ssaString));
Bill Buzbeea114add2012-05-03 15:00:40 -0700666 break;
buzbeee3acd072012-02-25 17:03:10 -0800667 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700668 case kMirOpCopy: {
buzbee52a77fc2012-11-20 19:50:46 -0800669 RegLocation rlSrc = GetSrc(cUnit, mir, 0);
670 RegLocation rlDest = GetDest(cUnit, mir);
671 StoreValue(cUnit, rlDest, rlSrc);
Bill Buzbeea114add2012-05-03 15:00:40 -0700672 break;
673 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700674 case kMirOpFusedCmplFloat:
buzbee52a77fc2012-11-20 19:50:46 -0800675 GenFusedFPCmpBranch(cUnit, bb, mir, false /*gt bias*/, false /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700676 break;
677 case kMirOpFusedCmpgFloat:
buzbee52a77fc2012-11-20 19:50:46 -0800678 GenFusedFPCmpBranch(cUnit, bb, mir, true /*gt bias*/, false /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700679 break;
680 case kMirOpFusedCmplDouble:
buzbee52a77fc2012-11-20 19:50:46 -0800681 GenFusedFPCmpBranch(cUnit, bb, mir, false /*gt bias*/, true /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700682 break;
683 case kMirOpFusedCmpgDouble:
buzbee52a77fc2012-11-20 19:50:46 -0800684 GenFusedFPCmpBranch(cUnit, bb, mir, true /*gt bias*/, true /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700685 break;
686 case kMirOpFusedCmpLong:
buzbee52a77fc2012-11-20 19:50:46 -0800687 GenFusedLongCmpBranch(cUnit, bb, mir);
Bill Buzbeea114add2012-05-03 15:00:40 -0700688 break;
Bill Buzbeea114add2012-05-03 15:00:40 -0700689 default:
690 break;
691 }
buzbeee3acd072012-02-25 17:03:10 -0800692}
693
694/* Handle the content in each basic block */
buzbeeaad94382012-11-21 07:40:50 -0800695static bool MethodBlockCodeGen(CompilationUnit* cUnit, BasicBlock* bb)
buzbeee3acd072012-02-25 17:03:10 -0800696{
buzbee488a78c2012-09-10 15:55:34 -0700697 if (bb->blockType == kDead) return false;
buzbee8320f382012-09-11 16:29:42 -0700698 cUnit->currentDalvikOffset = bb->startOffset;
Bill Buzbeea114add2012-05-03 15:00:40 -0700699 MIR* mir;
buzbeea1da8a52012-07-09 14:00:21 -0700700 LIR* labelList = cUnit->blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700701 int blockId = bb->id;
buzbeee3acd072012-02-25 17:03:10 -0800702
Bill Buzbeea114add2012-05-03 15:00:40 -0700703 cUnit->curBlock = bb;
704 labelList[blockId].operands[0] = bb->startOffset;
buzbeee3acd072012-02-25 17:03:10 -0800705
Bill Buzbeea114add2012-05-03 15:00:40 -0700706 /* Insert the block label */
707 labelList[blockId].opcode = kPseudoNormalBlockLabel;
buzbee52a77fc2012-11-20 19:50:46 -0800708 AppendLIR(cUnit, &labelList[blockId]);
buzbeee3acd072012-02-25 17:03:10 -0800709
buzbee8320f382012-09-11 16:29:42 -0700710 LIR* headLIR = NULL;
711
Bill Buzbeea5b30242012-09-28 07:19:44 -0700712 /* If this is a catch block, export the start address */
buzbee8320f382012-09-11 16:29:42 -0700713 if (bb->catchEntry) {
buzbee52a77fc2012-11-20 19:50:46 -0800714 headLIR = NewLIR0(cUnit, kPseudoExportedPC);
buzbee8320f382012-09-11 16:29:42 -0700715 }
716
Bill Buzbeea114add2012-05-03 15:00:40 -0700717 /* Free temp registers and reset redundant store tracking */
buzbee52a77fc2012-11-20 19:50:46 -0800718 ResetRegPool(cUnit);
719 ResetDefTracking(cUnit);
Bill Buzbeea114add2012-05-03 15:00:40 -0700720
buzbee52a77fc2012-11-20 19:50:46 -0800721 ClobberAllRegs(cUnit);
Bill Buzbeea114add2012-05-03 15:00:40 -0700722
Bill Buzbeea114add2012-05-03 15:00:40 -0700723
724 if (bb->blockType == kEntryBlock) {
buzbeead8f15e2012-06-18 14:49:45 -0700725 int startVReg = cUnit->numDalvikRegisters - cUnit->numIns;
buzbee52a77fc2012-11-20 19:50:46 -0800726 GenEntrySequence(cUnit, &cUnit->regLocation[startVReg],
buzbeead8f15e2012-06-18 14:49:45 -0700727 cUnit->regLocation[cUnit->methodSReg]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700728 } else if (bb->blockType == kExitBlock) {
buzbee52a77fc2012-11-20 19:50:46 -0800729 GenExitSequence(cUnit);
Bill Buzbeea114add2012-05-03 15:00:40 -0700730 }
731
732 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
buzbee52a77fc2012-11-20 19:50:46 -0800733 ResetRegPool(cUnit);
Bill Buzbeea114add2012-05-03 15:00:40 -0700734 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
buzbee52a77fc2012-11-20 19:50:46 -0800735 ClobberAllRegs(cUnit);
buzbeee1965672012-03-11 18:39:19 -0700736 }
737
Bill Buzbeea114add2012-05-03 15:00:40 -0700738 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
buzbee52a77fc2012-11-20 19:50:46 -0800739 ResetDefTracking(cUnit);
buzbeee3acd072012-02-25 17:03:10 -0800740 }
741
buzbee3d661942012-03-14 17:37:27 -0700742#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700743 /* Reset temp tracking sanity check */
744 cUnit->liveSReg = INVALID_SREG;
buzbee3d661942012-03-14 17:37:27 -0700745#endif
746
Bill Buzbeea114add2012-05-03 15:00:40 -0700747 cUnit->currentDalvikOffset = mir->offset;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700748 int opcode = mir->dalvikInsn.opcode;
Bill Buzbeea114add2012-05-03 15:00:40 -0700749 LIR* boundaryLIR;
buzbeee3acd072012-02-25 17:03:10 -0800750
Bill Buzbeea114add2012-05-03 15:00:40 -0700751 /* Mark the beginning of a Dalvik instruction for line tracking */
752 char* instStr = cUnit->printMe ?
buzbee52a77fc2012-11-20 19:50:46 -0800753 GetDalvikDisassembly(cUnit, mir->dalvikInsn, "") : NULL;
754 boundaryLIR = MarkBoundary(cUnit, mir->offset, instStr);
Bill Buzbeea114add2012-05-03 15:00:40 -0700755 /* Remember the first LIR for this block */
756 if (headLIR == NULL) {
757 headLIR = boundaryLIR;
758 /* Set the first boundaryLIR as a scheduling barrier */
759 headLIR->defMask = ENCODE_ALL;
buzbeee3acd072012-02-25 17:03:10 -0800760 }
761
Bill Buzbeea114add2012-05-03 15:00:40 -0700762 /* Don't generate the SSA annotation unless verbose mode is on */
763 if (cUnit->printMe && mir->ssaRep) {
buzbee52a77fc2012-11-20 19:50:46 -0800764 char* ssaString = GetSSAString(cUnit, mir->ssaRep);
765 NewLIR1(cUnit, kPseudoSSARep, reinterpret_cast<uintptr_t>(ssaString));
Bill Buzbeea114add2012-05-03 15:00:40 -0700766 }
767
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700768 if (opcode == kMirOpCheck) {
769 // Combine check and work halves of throwing instruction.
770 MIR* workHalf = mir->meta.throwInsn;
771 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
772 opcode = workHalf->dalvikInsn.opcode;
773 SSARepresentation* ssaRep = workHalf->ssaRep;
774 workHalf->ssaRep = mir->ssaRep;
775 mir->ssaRep = ssaRep;
776 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
777 }
778
779 if (opcode >= kMirOpFirst) {
buzbee52a77fc2012-11-20 19:50:46 -0800780 HandleExtendedMethodMIR(cUnit, bb, mir);
Bill Buzbeea114add2012-05-03 15:00:40 -0700781 continue;
782 }
783
buzbee52a77fc2012-11-20 19:50:46 -0800784 bool notHandled = CompileDalvikInstruction(cUnit, mir, bb, labelList);
Bill Buzbeea114add2012-05-03 15:00:40 -0700785 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700786 LOG(FATAL) << StringPrintf("%#06x: Opcode %#x (%s)",
787 mir->offset, opcode,
788 Instruction::Name(mir->dalvikInsn.opcode));
Bill Buzbeea114add2012-05-03 15:00:40 -0700789 }
790 }
791
792 if (headLIR) {
793 /*
794 * Eliminate redundant loads/stores and delay stores into later
795 * slots
796 */
buzbee52a77fc2012-11-20 19:50:46 -0800797 ApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
Bill Buzbeea114add2012-05-03 15:00:40 -0700798
799 /*
800 * Generate an unconditional branch to the fallthrough block.
801 */
802 if (bb->fallThrough) {
buzbee52a77fc2012-11-20 19:50:46 -0800803 OpUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700804 }
805 }
806 return false;
buzbeee3acd072012-02-25 17:03:10 -0800807}
808
buzbee52a77fc2012-11-20 19:50:46 -0800809void SpecialMIR2LIR(CompilationUnit* cUnit, SpecialCaseHandler specialCase)
buzbee16da88c2012-03-20 10:38:17 -0700810{
Bill Buzbeea114add2012-05-03 15:00:40 -0700811 /* Find the first DalvikByteCode block */
812 int numReachableBlocks = cUnit->numReachableBlocks;
813 const GrowableList *blockList = &cUnit->blockList;
814 BasicBlock*bb = NULL;
815 for (int idx = 0; idx < numReachableBlocks; idx++) {
816 int dfsIndex = cUnit->dfsOrder.elemList[idx];
buzbee52a77fc2012-11-20 19:50:46 -0800817 bb = reinterpret_cast<BasicBlock*>(GrowableListGetElement(blockList, dfsIndex));
Bill Buzbeea114add2012-05-03 15:00:40 -0700818 if (bb->blockType == kDalvikByteCode) {
819 break;
buzbee16da88c2012-03-20 10:38:17 -0700820 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700821 }
822 if (bb == NULL) {
823 return;
824 }
825 DCHECK_EQ(bb->startOffset, 0);
Elliott Hughes74847412012-06-20 18:10:21 -0700826 DCHECK(bb->firstMIRInsn != NULL);
buzbee16da88c2012-03-20 10:38:17 -0700827
Bill Buzbeea114add2012-05-03 15:00:40 -0700828 /* Get the first instruction */
829 MIR* mir = bb->firstMIRInsn;
buzbee16da88c2012-03-20 10:38:17 -0700830
Bill Buzbeea114add2012-05-03 15:00:40 -0700831 /* Free temp registers and reset redundant store tracking */
buzbee52a77fc2012-11-20 19:50:46 -0800832 ResetRegPool(cUnit);
833 ResetDefTracking(cUnit);
834 ClobberAllRegs(cUnit);
buzbee16da88c2012-03-20 10:38:17 -0700835
buzbee52a77fc2012-11-20 19:50:46 -0800836 GenSpecialCase(cUnit, bb, mir, specialCase);
buzbee16da88c2012-03-20 10:38:17 -0700837}
838
buzbee52a77fc2012-11-20 19:50:46 -0800839void MethodMIR2LIR(CompilationUnit* cUnit)
buzbeee3acd072012-02-25 17:03:10 -0800840{
Bill Buzbeea114add2012-05-03 15:00:40 -0700841 /* Used to hold the labels of each block */
842 cUnit->blockLabelList =
buzbee52a77fc2012-11-20 19:50:46 -0800843 static_cast<LIR*>(NewMem(cUnit, sizeof(LIR) * cUnit->numBlocks, true, kAllocLIR));
buzbeee3acd072012-02-25 17:03:10 -0800844
buzbee52a77fc2012-11-20 19:50:46 -0800845 DataFlowAnalysisDispatcher(cUnit, MethodBlockCodeGen,
Bill Buzbeea114add2012-05-03 15:00:40 -0700846 kPreOrderDFSTraversal, false /* Iterative */);
Ian Rogersab2b55d2012-03-18 00:06:11 -0700847
buzbee52a77fc2012-11-20 19:50:46 -0800848 HandleSuspendLaunchPads(cUnit);
buzbeee3acd072012-02-25 17:03:10 -0800849
buzbee52a77fc2012-11-20 19:50:46 -0800850 HandleThrowLaunchPads(cUnit);
buzbeee3acd072012-02-25 17:03:10 -0800851
buzbee52a77fc2012-11-20 19:50:46 -0800852 HandleIntrinsicLaunchPads(cUnit);
buzbeefc9e6fa2012-03-23 15:14:29 -0700853
Bill Buzbeea114add2012-05-03 15:00:40 -0700854 if (!(cUnit->disableOpt & (1 << kSafeOptimizations))) {
buzbee52a77fc2012-11-20 19:50:46 -0800855 RemoveRedundantBranches(cUnit);
Bill Buzbeea114add2012-05-03 15:00:40 -0700856 }
buzbeee3acd072012-02-25 17:03:10 -0800857}
858
buzbeee3acd072012-02-25 17:03:10 -0800859} // namespace art