blob: 3dc6d59a9be1809a292e4c9a273477ffb1cd72b5 [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
buzbeee3acd072012-02-25 17:03:10 -080026/*
27 * Target-independent code generation. Use only high-level
28 * load/store utilities here, or target-dependent genXX() handlers
29 * when necessary.
30 */
buzbeefa57c472012-11-21 12:06:18 -080031static bool CompileDalvikInstruction(CompilationUnit* cu, MIR* mir, BasicBlock* bb,
32 LIR* label_list)
buzbeee3acd072012-02-25 17:03:10 -080033{
buzbee02031b12012-11-23 09:41:35 -080034 Codegen* cg = cu->cg.get();
Bill Buzbeea114add2012-05-03 15:00:40 -070035 bool res = false; // Assume success
buzbeefa57c472012-11-21 12:06:18 -080036 RegLocation rl_src[3];
buzbee02031b12012-11-23 09:41:35 -080037 RegLocation rl_dest = GetBadLoc();
38 RegLocation rl_result = GetBadLoc();
Bill Buzbeea114add2012-05-03 15:00:40 -070039 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -080040 int opt_flags = mir->optimization_flags;
buzbee408ad162012-06-06 16:45:18 -070041 uint32_t vB = mir->dalvikInsn.vB;
42 uint32_t vC = mir->dalvikInsn.vC;
buzbeee3acd072012-02-25 17:03:10 -080043
buzbee02031b12012-11-23 09:41:35 -080044 // Prep Src and Dest locations.
buzbeefa57c472012-11-21 12:06:18 -080045 int next_sreg = 0;
46 int next_loc = 0;
47 int attrs = oat_data_flow_attributes[opcode];
buzbee02031b12012-11-23 09:41:35 -080048 rl_src[0] = rl_src[1] = rl_src[2] = GetBadLoc();
Bill Buzbeea114add2012-05-03 15:00:40 -070049 if (attrs & DF_UA) {
buzbeebff24652012-05-06 16:22:05 -070050 if (attrs & DF_A_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -080051 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
52 next_sreg+= 2;
buzbeebff24652012-05-06 16:22:05 -070053 } else {
buzbeefa57c472012-11-21 12:06:18 -080054 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
55 next_sreg++;
buzbeebff24652012-05-06 16:22:05 -070056 }
Bill Buzbeea114add2012-05-03 15:00:40 -070057 }
58 if (attrs & DF_UB) {
buzbeebff24652012-05-06 16:22:05 -070059 if (attrs & DF_B_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -080060 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
61 next_sreg+= 2;
buzbeebff24652012-05-06 16:22:05 -070062 } else {
buzbeefa57c472012-11-21 12:06:18 -080063 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
64 next_sreg++;
buzbeebff24652012-05-06 16:22:05 -070065 }
Bill Buzbeea114add2012-05-03 15:00:40 -070066 }
67 if (attrs & DF_UC) {
buzbeebff24652012-05-06 16:22:05 -070068 if (attrs & DF_C_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -080069 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
buzbeebff24652012-05-06 16:22:05 -070070 } else {
buzbeefa57c472012-11-21 12:06:18 -080071 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
buzbeebff24652012-05-06 16:22:05 -070072 }
Bill Buzbeea114add2012-05-03 15:00:40 -070073 }
74 if (attrs & DF_DA) {
buzbeebff24652012-05-06 16:22:05 -070075 if (attrs & DF_A_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -080076 rl_dest = GetDestWide(cu, mir);
buzbeebff24652012-05-06 16:22:05 -070077 } else {
buzbeefa57c472012-11-21 12:06:18 -080078 rl_dest = GetDest(cu, mir);
buzbeebff24652012-05-06 16:22:05 -070079 }
Bill Buzbeea114add2012-05-03 15:00:40 -070080 }
Bill Buzbeea114add2012-05-03 15:00:40 -070081 switch (opcode) {
82 case Instruction::NOP:
83 break;
buzbeee3acd072012-02-25 17:03:10 -080084
Ian Rogers474b6da2012-09-25 00:20:38 -070085 case Instruction::MOVE_EXCEPTION:
buzbee02031b12012-11-23 09:41:35 -080086 cg->GenMoveException(cu, rl_dest);
Bill Buzbeea114add2012-05-03 15:00:40 -070087 break;
Bill Buzbeea114add2012-05-03 15:00:40 -070088 case Instruction::RETURN_VOID:
buzbeefa57c472012-11-21 12:06:18 -080089 if (!(cu->attrs & METHOD_IS_LEAF)) {
buzbee02031b12012-11-23 09:41:35 -080090 cg->GenSuspendTest(cu, opt_flags);
Bill Buzbeea114add2012-05-03 15:00:40 -070091 }
92 break;
93
94 case Instruction::RETURN:
95 case Instruction::RETURN_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -080096 if (!(cu->attrs & METHOD_IS_LEAF)) {
buzbee02031b12012-11-23 09:41:35 -080097 cg->GenSuspendTest(cu, opt_flags);
Bill Buzbeea114add2012-05-03 15:00:40 -070098 }
buzbee02031b12012-11-23 09:41:35 -080099 cg->StoreValue(cu, GetReturn(cu, cu->shorty[0] == 'F'), rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700100 break;
101
102 case Instruction::RETURN_WIDE:
buzbeefa57c472012-11-21 12:06:18 -0800103 if (!(cu->attrs & METHOD_IS_LEAF)) {
buzbee02031b12012-11-23 09:41:35 -0800104 cg->GenSuspendTest(cu, opt_flags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700105 }
buzbee02031b12012-11-23 09:41:35 -0800106 cg->StoreValueWide(cu, GetReturnWide(cu,
buzbeefa57c472012-11-21 12:06:18 -0800107 cu->shorty[0] == 'D'), rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700108 break;
109
110 case Instruction::MOVE_RESULT_WIDE:
buzbeefa57c472012-11-21 12:06:18 -0800111 if (opt_flags & MIR_INLINED)
buzbee02031b12012-11-23 09:41:35 -0800112 break; // Nop - combined w/ previous invoke.
113 cg->StoreValueWide(cu, rl_dest, GetReturnWide(cu, rl_dest.fp));
Bill Buzbeea114add2012-05-03 15:00:40 -0700114 break;
115
116 case Instruction::MOVE_RESULT:
117 case Instruction::MOVE_RESULT_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -0800118 if (opt_flags & MIR_INLINED)
buzbee02031b12012-11-23 09:41:35 -0800119 break; // Nop - combined w/ previous invoke.
120 cg->StoreValue(cu, rl_dest, GetReturn(cu, rl_dest.fp));
Bill Buzbeea114add2012-05-03 15:00:40 -0700121 break;
122
123 case Instruction::MOVE:
124 case Instruction::MOVE_OBJECT:
125 case Instruction::MOVE_16:
126 case Instruction::MOVE_OBJECT_16:
127 case Instruction::MOVE_FROM16:
128 case Instruction::MOVE_OBJECT_FROM16:
buzbee02031b12012-11-23 09:41:35 -0800129 cg->StoreValue(cu, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700130 break;
131
132 case Instruction::MOVE_WIDE:
133 case Instruction::MOVE_WIDE_16:
134 case Instruction::MOVE_WIDE_FROM16:
buzbee02031b12012-11-23 09:41:35 -0800135 cg->StoreValueWide(cu, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700136 break;
137
138 case Instruction::CONST:
139 case Instruction::CONST_4:
140 case Instruction::CONST_16:
buzbeefa57c472012-11-21 12:06:18 -0800141 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee02031b12012-11-23 09:41:35 -0800142 cg->LoadConstantNoClobber(cu, rl_result.low_reg, vB);
143 cg->StoreValue(cu, rl_dest, rl_result);
buzbee5f61f672012-11-28 17:22:17 -0800144 cg->Workaround7250540(cu, rl_dest, vB);
Bill Buzbeea114add2012-05-03 15:00:40 -0700145 break;
146
147 case Instruction::CONST_HIGH16:
buzbeefa57c472012-11-21 12:06:18 -0800148 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee02031b12012-11-23 09:41:35 -0800149 cg->LoadConstantNoClobber(cu, rl_result.low_reg, vB << 16);
150 cg->StoreValue(cu, rl_dest, rl_result);
buzbee5f61f672012-11-28 17:22:17 -0800151 cg->Workaround7250540(cu, rl_dest, vB);
Bill Buzbeea114add2012-05-03 15:00:40 -0700152 break;
153
154 case Instruction::CONST_WIDE_16:
155 case Instruction::CONST_WIDE_32:
buzbeefa57c472012-11-21 12:06:18 -0800156 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee02031b12012-11-23 09:41:35 -0800157 cg->LoadConstantValueWide(cu, rl_result.low_reg, rl_result.high_reg, vB,
buzbee408ad162012-06-06 16:45:18 -0700158 (vB & 0x80000000) ? -1 : 0);
buzbee02031b12012-11-23 09:41:35 -0800159 cg->StoreValueWide(cu, rl_dest, rl_result);
Bill Buzbeea114add2012-05-03 15:00:40 -0700160 break;
161
162 case Instruction::CONST_WIDE:
buzbeefa57c472012-11-21 12:06:18 -0800163 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee02031b12012-11-23 09:41:35 -0800164 cg->LoadConstantValueWide(cu, rl_result.low_reg, rl_result.high_reg,
Bill Buzbeea114add2012-05-03 15:00:40 -0700165 mir->dalvikInsn.vB_wide & 0xffffffff,
166 (mir->dalvikInsn.vB_wide >> 32) & 0xffffffff);
buzbee02031b12012-11-23 09:41:35 -0800167 cg->StoreValueWide(cu, rl_dest, rl_result);
Bill Buzbeea114add2012-05-03 15:00:40 -0700168 break;
169
170 case Instruction::CONST_WIDE_HIGH16:
buzbeefa57c472012-11-21 12:06:18 -0800171 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee02031b12012-11-23 09:41:35 -0800172 cg->LoadConstantValueWide(cu, rl_result.low_reg, rl_result.high_reg,
buzbee408ad162012-06-06 16:45:18 -0700173 0, vB << 16);
buzbee02031b12012-11-23 09:41:35 -0800174 cg->StoreValueWide(cu, rl_dest, rl_result);
Bill Buzbeea114add2012-05-03 15:00:40 -0700175 break;
176
177 case Instruction::MONITOR_ENTER:
buzbee02031b12012-11-23 09:41:35 -0800178 cg->GenMonitorEnter(cu, opt_flags, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700179 break;
180
181 case Instruction::MONITOR_EXIT:
buzbee02031b12012-11-23 09:41:35 -0800182 cg->GenMonitorExit(cu, opt_flags, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700183 break;
184
185 case Instruction::CHECK_CAST:
buzbee02031b12012-11-23 09:41:35 -0800186 cg->GenCheckCast(cu, vB, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700187 break;
188
189 case Instruction::INSTANCE_OF:
buzbee02031b12012-11-23 09:41:35 -0800190 cg->GenInstanceof(cu, vC, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700191 break;
192
193 case Instruction::NEW_INSTANCE:
buzbee02031b12012-11-23 09:41:35 -0800194 cg->GenNewInstance(cu, vB, rl_dest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700195 break;
196
197 case Instruction::THROW:
buzbee02031b12012-11-23 09:41:35 -0800198 cg->GenThrow(cu, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700199 break;
200
Bill Buzbeea114add2012-05-03 15:00:40 -0700201 case Instruction::ARRAY_LENGTH:
buzbeefa57c472012-11-21 12:06:18 -0800202 int len_offset;
203 len_offset = Array::LengthOffset().Int32Value();
buzbee02031b12012-11-23 09:41:35 -0800204 rl_src[0] = cg->LoadValue(cu, rl_src[0], kCoreReg);
205 cg->GenNullCheck(cu, rl_src[0].s_reg_low, rl_src[0].low_reg, opt_flags);
buzbeefa57c472012-11-21 12:06:18 -0800206 rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
buzbee02031b12012-11-23 09:41:35 -0800207 cg->LoadWordDisp(cu, rl_src[0].low_reg, len_offset, rl_result.low_reg);
208 cg->StoreValue(cu, rl_dest, rl_result);
Bill Buzbeea114add2012-05-03 15:00:40 -0700209 break;
210
211 case Instruction::CONST_STRING:
212 case Instruction::CONST_STRING_JUMBO:
buzbee02031b12012-11-23 09:41:35 -0800213 cg->GenConstString(cu, vB, rl_dest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700214 break;
215
216 case Instruction::CONST_CLASS:
buzbee02031b12012-11-23 09:41:35 -0800217 cg->GenConstClass(cu, vB, rl_dest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700218 break;
219
220 case Instruction::FILL_ARRAY_DATA:
buzbee02031b12012-11-23 09:41:35 -0800221 cg->GenFillArrayData(cu, vB, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700222 break;
223
224 case Instruction::FILLED_NEW_ARRAY:
buzbee02031b12012-11-23 09:41:35 -0800225 cg->GenFilledNewArray(cu, cg->NewMemCallInfo(cu, bb, mir, kStatic,
buzbee3b3dbdd2012-06-13 13:39:34 -0700226 false /* not range */));
Bill Buzbeea114add2012-05-03 15:00:40 -0700227 break;
228
229 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800230 cg->GenFilledNewArray(cu, cg->NewMemCallInfo(cu, bb, mir, kStatic,
buzbee3b3dbdd2012-06-13 13:39:34 -0700231 true /* range */));
Bill Buzbeea114add2012-05-03 15:00:40 -0700232 break;
233
234 case Instruction::NEW_ARRAY:
buzbee02031b12012-11-23 09:41:35 -0800235 cg->GenNewArray(cu, vC, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700236 break;
237
238 case Instruction::GOTO:
239 case Instruction::GOTO_16:
240 case Instruction::GOTO_32:
buzbeefa57c472012-11-21 12:06:18 -0800241 if (bb->taken->start_offset <= mir->offset) {
buzbee02031b12012-11-23 09:41:35 -0800242 cg->GenSuspendTestAndBranch(cu, opt_flags, &label_list[bb->taken->id]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700243 } else {
buzbee02031b12012-11-23 09:41:35 -0800244 cg->OpUnconditionalBranch(cu, &label_list[bb->taken->id]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700245 }
246 break;
247
248 case Instruction::PACKED_SWITCH:
buzbee02031b12012-11-23 09:41:35 -0800249 cg->GenPackedSwitch(cu, vB, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700250 break;
251
252 case Instruction::SPARSE_SWITCH:
buzbee02031b12012-11-23 09:41:35 -0800253 cg->GenSparseSwitch(cu, vB, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700254 break;
255
256 case Instruction::CMPL_FLOAT:
257 case Instruction::CMPG_FLOAT:
258 case Instruction::CMPL_DOUBLE:
259 case Instruction::CMPG_DOUBLE:
buzbee02031b12012-11-23 09:41:35 -0800260 res = cg->GenCmpFP(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700261 break;
262
263 case Instruction::CMP_LONG:
buzbee02031b12012-11-23 09:41:35 -0800264 cg->GenCmpLong(cu, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700265 break;
266
267 case Instruction::IF_EQ:
268 case Instruction::IF_NE:
269 case Instruction::IF_LT:
270 case Instruction::IF_GE:
271 case Instruction::IF_GT:
272 case Instruction::IF_LE: {
buzbeefa57c472012-11-21 12:06:18 -0800273 LIR* taken = &label_list[bb->taken->id];
274 LIR* fall_through = &label_list[bb->fall_through->id];
275 bool backward_branch;
276 backward_branch = (bb->taken->start_offset <= mir->offset);
277 if (backward_branch) {
buzbee02031b12012-11-23 09:41:35 -0800278 cg->GenSuspendTest(cu, opt_flags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700279 }
buzbee02031b12012-11-23 09:41:35 -0800280 cg->GenCompareAndBranch(cu, opcode, rl_src[0], rl_src[1], taken,
buzbeefa57c472012-11-21 12:06:18 -0800281 fall_through);
Bill Buzbeea114add2012-05-03 15:00:40 -0700282 break;
283 }
284
285 case Instruction::IF_EQZ:
286 case Instruction::IF_NEZ:
287 case Instruction::IF_LTZ:
288 case Instruction::IF_GEZ:
289 case Instruction::IF_GTZ:
290 case Instruction::IF_LEZ: {
buzbeefa57c472012-11-21 12:06:18 -0800291 LIR* taken = &label_list[bb->taken->id];
292 LIR* fall_through = &label_list[bb->fall_through->id];
293 bool backward_branch;
294 backward_branch = (bb->taken->start_offset <= mir->offset);
295 if (backward_branch) {
buzbee02031b12012-11-23 09:41:35 -0800296 cg->GenSuspendTest(cu, opt_flags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700297 }
buzbee02031b12012-11-23 09:41:35 -0800298 cg->GenCompareZeroAndBranch(cu, opcode, rl_src[0], taken, fall_through);
Bill Buzbeea114add2012-05-03 15:00:40 -0700299 break;
300 }
301
302 case Instruction::AGET_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800303 cg->GenArrayGet(cu, opt_flags, kLong, rl_src[0], rl_src[1], rl_dest, 3);
Bill Buzbeea114add2012-05-03 15:00:40 -0700304 break;
305 case Instruction::AGET:
306 case Instruction::AGET_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800307 cg->GenArrayGet(cu, opt_flags, kWord, rl_src[0], rl_src[1], rl_dest, 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700308 break;
309 case Instruction::AGET_BOOLEAN:
buzbee02031b12012-11-23 09:41:35 -0800310 cg->GenArrayGet(cu, opt_flags, kUnsignedByte, rl_src[0], rl_src[1], rl_dest, 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700311 break;
312 case Instruction::AGET_BYTE:
buzbee02031b12012-11-23 09:41:35 -0800313 cg->GenArrayGet(cu, opt_flags, kSignedByte, rl_src[0], rl_src[1], rl_dest, 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700314 break;
315 case Instruction::AGET_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800316 cg->GenArrayGet(cu, opt_flags, kUnsignedHalf, rl_src[0], rl_src[1], rl_dest, 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700317 break;
318 case Instruction::AGET_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800319 cg->GenArrayGet(cu, opt_flags, kSignedHalf, rl_src[0], rl_src[1], rl_dest, 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700320 break;
321 case Instruction::APUT_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800322 cg->GenArrayPut(cu, opt_flags, kLong, rl_src[1], rl_src[2], rl_src[0], 3);
Bill Buzbeea114add2012-05-03 15:00:40 -0700323 break;
324 case Instruction::APUT:
buzbee02031b12012-11-23 09:41:35 -0800325 cg->GenArrayPut(cu, opt_flags, kWord, rl_src[1], rl_src[2], rl_src[0], 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700326 break;
327 case Instruction::APUT_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800328 cg->GenArrayObjPut(cu, opt_flags, rl_src[1], rl_src[2], rl_src[0], 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700329 break;
330 case Instruction::APUT_SHORT:
331 case Instruction::APUT_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800332 cg->GenArrayPut(cu, opt_flags, kUnsignedHalf, rl_src[1], rl_src[2], rl_src[0], 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700333 break;
334 case Instruction::APUT_BYTE:
335 case Instruction::APUT_BOOLEAN:
buzbee02031b12012-11-23 09:41:35 -0800336 cg->GenArrayPut(cu, opt_flags, kUnsignedByte, rl_src[1], rl_src[2],
buzbeefa57c472012-11-21 12:06:18 -0800337 rl_src[0], 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700338 break;
339
340 case Instruction::IGET_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800341 cg->GenIGet(cu, vC, opt_flags, kWord, rl_dest, rl_src[0], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700342 break;
343
344 case Instruction::IGET_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800345 cg->GenIGet(cu, vC, opt_flags, kLong, rl_dest, rl_src[0], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700346 break;
347
348 case Instruction::IGET:
buzbee02031b12012-11-23 09:41:35 -0800349 cg->GenIGet(cu, vC, opt_flags, kWord, rl_dest, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700350 break;
351
352 case Instruction::IGET_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800353 cg->GenIGet(cu, vC, opt_flags, kUnsignedHalf, rl_dest, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700354 break;
355
356 case Instruction::IGET_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800357 cg->GenIGet(cu, vC, opt_flags, kSignedHalf, rl_dest, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700358 break;
359
360 case Instruction::IGET_BOOLEAN:
361 case Instruction::IGET_BYTE:
buzbee02031b12012-11-23 09:41:35 -0800362 cg->GenIGet(cu, vC, opt_flags, kUnsignedByte, rl_dest, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700363 break;
364
365 case Instruction::IPUT_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800366 cg->GenIPut(cu, vC, opt_flags, kLong, rl_src[0], rl_src[1], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700367 break;
368
369 case Instruction::IPUT_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800370 cg->GenIPut(cu, vC, opt_flags, kWord, rl_src[0], rl_src[1], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700371 break;
372
373 case Instruction::IPUT:
buzbee02031b12012-11-23 09:41:35 -0800374 cg->GenIPut(cu, vC, opt_flags, kWord, rl_src[0], rl_src[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700375 break;
376
377 case Instruction::IPUT_BOOLEAN:
378 case Instruction::IPUT_BYTE:
buzbee02031b12012-11-23 09:41:35 -0800379 cg->GenIPut(cu, vC, opt_flags, kUnsignedByte, rl_src[0], rl_src[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700380 break;
381
382 case Instruction::IPUT_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800383 cg->GenIPut(cu, vC, opt_flags, kUnsignedHalf, rl_src[0], rl_src[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700384 break;
385
386 case Instruction::IPUT_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800387 cg->GenIPut(cu, vC, opt_flags, kSignedHalf, rl_src[0], rl_src[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700388 break;
389
390 case Instruction::SGET_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800391 cg->GenSget(cu, vB, rl_dest, false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700392 break;
393 case Instruction::SGET:
394 case Instruction::SGET_BOOLEAN:
395 case Instruction::SGET_BYTE:
396 case Instruction::SGET_CHAR:
397 case Instruction::SGET_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800398 cg->GenSget(cu, vB, rl_dest, false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700399 break;
400
401 case Instruction::SGET_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800402 cg->GenSget(cu, vB, rl_dest, true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700403 break;
404
405 case Instruction::SPUT_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800406 cg->GenSput(cu, vB, rl_src[0], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700407 break;
408
409 case Instruction::SPUT:
410 case Instruction::SPUT_BOOLEAN:
411 case Instruction::SPUT_BYTE:
412 case Instruction::SPUT_CHAR:
413 case Instruction::SPUT_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800414 cg->GenSput(cu, vB, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700415 break;
416
417 case Instruction::SPUT_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800418 cg->GenSput(cu, vB, rl_src[0], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700419 break;
420
421 case Instruction::INVOKE_STATIC_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800422 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kStatic, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700423 break;
424 case Instruction::INVOKE_STATIC:
buzbee02031b12012-11-23 09:41:35 -0800425 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kStatic, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700426 break;
427
428 case Instruction::INVOKE_DIRECT:
buzbee02031b12012-11-23 09:41:35 -0800429 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kDirect, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700430 break;
431 case Instruction::INVOKE_DIRECT_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800432 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kDirect, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700433 break;
434
435 case Instruction::INVOKE_VIRTUAL:
buzbee02031b12012-11-23 09:41:35 -0800436 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kVirtual, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700437 break;
438 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800439 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kVirtual, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700440 break;
441
442 case Instruction::INVOKE_SUPER:
buzbee02031b12012-11-23 09:41:35 -0800443 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kSuper, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700444 break;
445 case Instruction::INVOKE_SUPER_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800446 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kSuper, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700447 break;
448
449 case Instruction::INVOKE_INTERFACE:
buzbee02031b12012-11-23 09:41:35 -0800450 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kInterface, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700451 break;
452 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800453 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kInterface, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700454 break;
455
456 case Instruction::NEG_INT:
457 case Instruction::NOT_INT:
buzbee02031b12012-11-23 09:41:35 -0800458 res = cg->GenArithOpInt(cu, opcode, rl_dest, rl_src[0], rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700459 break;
460
461 case Instruction::NEG_LONG:
462 case Instruction::NOT_LONG:
buzbee02031b12012-11-23 09:41:35 -0800463 res = cg->GenArithOpLong(cu, opcode, rl_dest, rl_src[0], rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700464 break;
465
466 case Instruction::NEG_FLOAT:
buzbee02031b12012-11-23 09:41:35 -0800467 res = cg->GenArithOpFloat(cu, opcode, rl_dest, rl_src[0], rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700468 break;
469
470 case Instruction::NEG_DOUBLE:
buzbee02031b12012-11-23 09:41:35 -0800471 res = cg->GenArithOpDouble(cu, opcode, rl_dest, rl_src[0], rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700472 break;
473
474 case Instruction::INT_TO_LONG:
buzbee02031b12012-11-23 09:41:35 -0800475 cg->GenIntToLong(cu, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700476 break;
477
478 case Instruction::LONG_TO_INT:
buzbeefa57c472012-11-21 12:06:18 -0800479 rl_src[0] = UpdateLocWide(cu, rl_src[0]);
480 rl_src[0] = WideToNarrow(cu, rl_src[0]);
buzbee02031b12012-11-23 09:41:35 -0800481 cg->StoreValue(cu, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700482 break;
483
484 case Instruction::INT_TO_BYTE:
485 case Instruction::INT_TO_SHORT:
486 case Instruction::INT_TO_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800487 cg->GenIntNarrowing(cu, opcode, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700488 break;
489
490 case Instruction::INT_TO_FLOAT:
491 case Instruction::INT_TO_DOUBLE:
492 case Instruction::LONG_TO_FLOAT:
493 case Instruction::LONG_TO_DOUBLE:
494 case Instruction::FLOAT_TO_INT:
495 case Instruction::FLOAT_TO_LONG:
496 case Instruction::FLOAT_TO_DOUBLE:
497 case Instruction::DOUBLE_TO_INT:
498 case Instruction::DOUBLE_TO_LONG:
499 case Instruction::DOUBLE_TO_FLOAT:
buzbee02031b12012-11-23 09:41:35 -0800500 cg->GenConversion(cu, opcode, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700501 break;
502
503 case Instruction::ADD_INT:
504 case Instruction::SUB_INT:
505 case Instruction::MUL_INT:
506 case Instruction::DIV_INT:
507 case Instruction::REM_INT:
508 case Instruction::AND_INT:
509 case Instruction::OR_INT:
510 case Instruction::XOR_INT:
511 case Instruction::SHL_INT:
512 case Instruction::SHR_INT:
513 case Instruction::USHR_INT:
514 case Instruction::ADD_INT_2ADDR:
515 case Instruction::SUB_INT_2ADDR:
516 case Instruction::MUL_INT_2ADDR:
517 case Instruction::DIV_INT_2ADDR:
518 case Instruction::REM_INT_2ADDR:
519 case Instruction::AND_INT_2ADDR:
520 case Instruction::OR_INT_2ADDR:
521 case Instruction::XOR_INT_2ADDR:
522 case Instruction::SHL_INT_2ADDR:
523 case Instruction::SHR_INT_2ADDR:
524 case Instruction::USHR_INT_2ADDR:
buzbee02031b12012-11-23 09:41:35 -0800525 cg->GenArithOpInt(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700526 break;
527
528 case Instruction::ADD_LONG:
529 case Instruction::SUB_LONG:
530 case Instruction::MUL_LONG:
531 case Instruction::DIV_LONG:
532 case Instruction::REM_LONG:
533 case Instruction::AND_LONG:
534 case Instruction::OR_LONG:
535 case Instruction::XOR_LONG:
536 case Instruction::ADD_LONG_2ADDR:
537 case Instruction::SUB_LONG_2ADDR:
538 case Instruction::MUL_LONG_2ADDR:
539 case Instruction::DIV_LONG_2ADDR:
540 case Instruction::REM_LONG_2ADDR:
541 case Instruction::AND_LONG_2ADDR:
542 case Instruction::OR_LONG_2ADDR:
543 case Instruction::XOR_LONG_2ADDR:
buzbee02031b12012-11-23 09:41:35 -0800544 cg->GenArithOpLong(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700545 break;
546
547 case Instruction::SHL_LONG:
548 case Instruction::SHR_LONG:
549 case Instruction::USHR_LONG:
550 case Instruction::SHL_LONG_2ADDR:
551 case Instruction::SHR_LONG_2ADDR:
552 case Instruction::USHR_LONG_2ADDR:
buzbee02031b12012-11-23 09:41:35 -0800553 cg->GenShiftOpLong(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700554 break;
555
556 case Instruction::ADD_FLOAT:
557 case Instruction::SUB_FLOAT:
558 case Instruction::MUL_FLOAT:
559 case Instruction::DIV_FLOAT:
560 case Instruction::REM_FLOAT:
561 case Instruction::ADD_FLOAT_2ADDR:
562 case Instruction::SUB_FLOAT_2ADDR:
563 case Instruction::MUL_FLOAT_2ADDR:
564 case Instruction::DIV_FLOAT_2ADDR:
565 case Instruction::REM_FLOAT_2ADDR:
buzbee02031b12012-11-23 09:41:35 -0800566 cg->GenArithOpFloat(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700567 break;
568
569 case Instruction::ADD_DOUBLE:
570 case Instruction::SUB_DOUBLE:
571 case Instruction::MUL_DOUBLE:
572 case Instruction::DIV_DOUBLE:
573 case Instruction::REM_DOUBLE:
574 case Instruction::ADD_DOUBLE_2ADDR:
575 case Instruction::SUB_DOUBLE_2ADDR:
576 case Instruction::MUL_DOUBLE_2ADDR:
577 case Instruction::DIV_DOUBLE_2ADDR:
578 case Instruction::REM_DOUBLE_2ADDR:
buzbee02031b12012-11-23 09:41:35 -0800579 cg->GenArithOpDouble(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700580 break;
581
582 case Instruction::RSUB_INT:
583 case Instruction::ADD_INT_LIT16:
584 case Instruction::MUL_INT_LIT16:
585 case Instruction::DIV_INT_LIT16:
586 case Instruction::REM_INT_LIT16:
587 case Instruction::AND_INT_LIT16:
588 case Instruction::OR_INT_LIT16:
589 case Instruction::XOR_INT_LIT16:
590 case Instruction::ADD_INT_LIT8:
591 case Instruction::RSUB_INT_LIT8:
592 case Instruction::MUL_INT_LIT8:
593 case Instruction::DIV_INT_LIT8:
594 case Instruction::REM_INT_LIT8:
595 case Instruction::AND_INT_LIT8:
596 case Instruction::OR_INT_LIT8:
597 case Instruction::XOR_INT_LIT8:
598 case Instruction::SHL_INT_LIT8:
599 case Instruction::SHR_INT_LIT8:
600 case Instruction::USHR_INT_LIT8:
buzbee02031b12012-11-23 09:41:35 -0800601 cg->GenArithOpIntLit(cu, opcode, rl_dest, rl_src[0], vC);
Bill Buzbeea114add2012-05-03 15:00:40 -0700602 break;
603
604 default:
605 res = true;
606 }
607 return res;
buzbeee3acd072012-02-25 17:03:10 -0800608}
609
buzbee02031b12012-11-23 09:41:35 -0800610// Process extended MIR instructions (such as PHI).
buzbeefa57c472012-11-21 12:06:18 -0800611static void HandleExtendedMethodMIR(CompilationUnit* cu, BasicBlock* bb, MIR* mir)
buzbeee3acd072012-02-25 17:03:10 -0800612{
buzbee02031b12012-11-23 09:41:35 -0800613 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -0800614 int op_offset = mir->dalvikInsn.opcode - kMirOpFirst;
Bill Buzbeea114add2012-05-03 15:00:40 -0700615 char* msg = NULL;
buzbeefa57c472012-11-21 12:06:18 -0800616 if (cu->verbose) {
617 msg = static_cast<char*>(NewMem(cu, strlen(extended_mir_op_names[op_offset]) + 1,
buzbeecbd6d442012-11-17 14:11:25 -0800618 false, kAllocDebugInfo));
buzbeefa57c472012-11-21 12:06:18 -0800619 strcpy(msg, extended_mir_op_names[op_offset]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700620 }
buzbeefa57c472012-11-21 12:06:18 -0800621 LIR* op = NewLIR1(cu, kPseudoExtended, reinterpret_cast<uintptr_t>(msg));
buzbeee3acd072012-02-25 17:03:10 -0800622
buzbeecbd6d442012-11-17 14:11:25 -0800623 switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700624 case kMirOpPhi: {
buzbeefa57c472012-11-21 12:06:18 -0800625 char* ssa_string = NULL;
626 if (cu->verbose) {
627 ssa_string = GetSSAString(cu, mir->ssa_rep);
Bill Buzbeea114add2012-05-03 15:00:40 -0700628 }
buzbeefa57c472012-11-21 12:06:18 -0800629 op->flags.is_nop = true;
630 NewLIR1(cu, kPseudoSSARep, reinterpret_cast<uintptr_t>(ssa_string));
Bill Buzbeea114add2012-05-03 15:00:40 -0700631 break;
buzbeee3acd072012-02-25 17:03:10 -0800632 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700633 case kMirOpCopy: {
buzbeefa57c472012-11-21 12:06:18 -0800634 RegLocation rl_src = GetSrc(cu, mir, 0);
635 RegLocation rl_dest = GetDest(cu, mir);
buzbee02031b12012-11-23 09:41:35 -0800636 cg->StoreValue(cu, rl_dest, rl_src);
Bill Buzbeea114add2012-05-03 15:00:40 -0700637 break;
638 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700639 case kMirOpFusedCmplFloat:
buzbee02031b12012-11-23 09:41:35 -0800640 cg->GenFusedFPCmpBranch(cu, bb, mir, false /*gt bias*/, false /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700641 break;
642 case kMirOpFusedCmpgFloat:
buzbee02031b12012-11-23 09:41:35 -0800643 cg->GenFusedFPCmpBranch(cu, bb, mir, true /*gt bias*/, false /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700644 break;
645 case kMirOpFusedCmplDouble:
buzbee02031b12012-11-23 09:41:35 -0800646 cg->GenFusedFPCmpBranch(cu, bb, mir, false /*gt bias*/, true /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700647 break;
648 case kMirOpFusedCmpgDouble:
buzbee02031b12012-11-23 09:41:35 -0800649 cg->GenFusedFPCmpBranch(cu, bb, mir, true /*gt bias*/, true /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700650 break;
651 case kMirOpFusedCmpLong:
buzbee02031b12012-11-23 09:41:35 -0800652 cg->GenFusedLongCmpBranch(cu, bb, mir);
Bill Buzbeea114add2012-05-03 15:00:40 -0700653 break;
Bill Buzbeea114add2012-05-03 15:00:40 -0700654 default:
655 break;
656 }
buzbeee3acd072012-02-25 17:03:10 -0800657}
658
buzbee02031b12012-11-23 09:41:35 -0800659// Handle the content in each basic block.
buzbeefa57c472012-11-21 12:06:18 -0800660static bool MethodBlockCodeGen(CompilationUnit* cu, BasicBlock* bb)
buzbeee3acd072012-02-25 17:03:10 -0800661{
buzbeefa57c472012-11-21 12:06:18 -0800662 if (bb->block_type == kDead) return false;
buzbee02031b12012-11-23 09:41:35 -0800663 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -0800664 cu->current_dalvik_offset = bb->start_offset;
Bill Buzbeea114add2012-05-03 15:00:40 -0700665 MIR* mir;
buzbeefa57c472012-11-21 12:06:18 -0800666 LIR* label_list = cu->block_label_list;
667 int block_id = bb->id;
buzbeee3acd072012-02-25 17:03:10 -0800668
buzbeefa57c472012-11-21 12:06:18 -0800669 cu->cur_block = bb;
670 label_list[block_id].operands[0] = bb->start_offset;
buzbeee3acd072012-02-25 17:03:10 -0800671
buzbee02031b12012-11-23 09:41:35 -0800672 // Insert the block label.
buzbeefa57c472012-11-21 12:06:18 -0800673 label_list[block_id].opcode = kPseudoNormalBlockLabel;
674 AppendLIR(cu, &label_list[block_id]);
buzbeee3acd072012-02-25 17:03:10 -0800675
buzbeefa57c472012-11-21 12:06:18 -0800676 LIR* head_lir = NULL;
buzbee8320f382012-09-11 16:29:42 -0700677
buzbee02031b12012-11-23 09:41:35 -0800678 // If this is a catch block, export the start address.
buzbeefa57c472012-11-21 12:06:18 -0800679 if (bb->catch_entry) {
680 head_lir = NewLIR0(cu, kPseudoExportedPC);
buzbee8320f382012-09-11 16:29:42 -0700681 }
682
buzbee02031b12012-11-23 09:41:35 -0800683 // Free temp registers and reset redundant store tracking.
buzbeefa57c472012-11-21 12:06:18 -0800684 ResetRegPool(cu);
685 ResetDefTracking(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700686
buzbeefa57c472012-11-21 12:06:18 -0800687 ClobberAllRegs(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700688
buzbeefa57c472012-11-21 12:06:18 -0800689 if (bb->block_type == kEntryBlock) {
690 int start_vreg = cu->num_dalvik_registers - cu->num_ins;
buzbee02031b12012-11-23 09:41:35 -0800691 cg->GenEntrySequence(cu, &cu->reg_location[start_vreg],
692 cu->reg_location[cu->method_sreg]);
buzbeefa57c472012-11-21 12:06:18 -0800693 } else if (bb->block_type == kExitBlock) {
buzbee02031b12012-11-23 09:41:35 -0800694 cg->GenExitSequence(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700695 }
696
buzbee28c9a832012-11-21 15:39:13 -0800697 for (mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
buzbeefa57c472012-11-21 12:06:18 -0800698 ResetRegPool(cu);
699 if (cu->disable_opt & (1 << kTrackLiveTemps)) {
700 ClobberAllRegs(cu);
buzbeee1965672012-03-11 18:39:19 -0700701 }
702
buzbeefa57c472012-11-21 12:06:18 -0800703 if (cu->disable_opt & (1 << kSuppressLoads)) {
704 ResetDefTracking(cu);
buzbeee3acd072012-02-25 17:03:10 -0800705 }
706
buzbee3d661942012-03-14 17:37:27 -0700707#ifndef NDEBUG
buzbee02031b12012-11-23 09:41:35 -0800708 // Reset temp tracking sanity check.
buzbeefa57c472012-11-21 12:06:18 -0800709 cu->live_sreg = INVALID_SREG;
buzbee3d661942012-03-14 17:37:27 -0700710#endif
711
buzbeefa57c472012-11-21 12:06:18 -0800712 cu->current_dalvik_offset = mir->offset;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700713 int opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -0800714 LIR* boundary_lir;
buzbeee3acd072012-02-25 17:03:10 -0800715
buzbee02031b12012-11-23 09:41:35 -0800716 // Mark the beginning of a Dalvik instruction for line tracking.
buzbeefa57c472012-11-21 12:06:18 -0800717 char* inst_str = cu->verbose ?
718 GetDalvikDisassembly(cu, mir->dalvikInsn, "") : NULL;
719 boundary_lir = MarkBoundary(cu, mir->offset, inst_str);
buzbee02031b12012-11-23 09:41:35 -0800720 // Remember the first LIR for this block.
buzbeefa57c472012-11-21 12:06:18 -0800721 if (head_lir == NULL) {
722 head_lir = boundary_lir;
buzbee02031b12012-11-23 09:41:35 -0800723 // Set the first boundary_lir as a scheduling barrier.
buzbeefa57c472012-11-21 12:06:18 -0800724 head_lir->def_mask = ENCODE_ALL;
buzbeee3acd072012-02-25 17:03:10 -0800725 }
726
buzbee02031b12012-11-23 09:41:35 -0800727 // Don't generate the SSA annotation unless verbose mode is on.
buzbeefa57c472012-11-21 12:06:18 -0800728 if (cu->verbose && mir->ssa_rep) {
729 char* ssa_string = GetSSAString(cu, mir->ssa_rep);
730 NewLIR1(cu, kPseudoSSARep, reinterpret_cast<uintptr_t>(ssa_string));
Bill Buzbeea114add2012-05-03 15:00:40 -0700731 }
732
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700733 if (opcode == kMirOpCheck) {
734 // Combine check and work halves of throwing instruction.
buzbeefa57c472012-11-21 12:06:18 -0800735 MIR* work_half = mir->meta.throw_insn;
736 mir->dalvikInsn.opcode = work_half->dalvikInsn.opcode;
737 opcode = work_half->dalvikInsn.opcode;
738 SSARepresentation* ssa_rep = work_half->ssa_rep;
739 work_half->ssa_rep = mir->ssa_rep;
740 mir->ssa_rep = ssa_rep;
741 work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700742 }
743
744 if (opcode >= kMirOpFirst) {
buzbeefa57c472012-11-21 12:06:18 -0800745 HandleExtendedMethodMIR(cu, bb, mir);
Bill Buzbeea114add2012-05-03 15:00:40 -0700746 continue;
747 }
748
buzbeefa57c472012-11-21 12:06:18 -0800749 bool not_handled = CompileDalvikInstruction(cu, mir, bb, label_list);
750 if (not_handled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700751 LOG(FATAL) << StringPrintf("%#06x: Opcode %#x (%s)",
752 mir->offset, opcode,
753 Instruction::Name(mir->dalvikInsn.opcode));
Bill Buzbeea114add2012-05-03 15:00:40 -0700754 }
755 }
756
buzbeefa57c472012-11-21 12:06:18 -0800757 if (head_lir) {
buzbee02031b12012-11-23 09:41:35 -0800758 // Eliminate redundant loads/stores and delay stores into later slots.
buzbeefa57c472012-11-21 12:06:18 -0800759 ApplyLocalOptimizations(cu, head_lir, cu->last_lir_insn);
Bill Buzbeea114add2012-05-03 15:00:40 -0700760
buzbee02031b12012-11-23 09:41:35 -0800761 // Generate an unconditional branch to the fallthrough block.
buzbeefa57c472012-11-21 12:06:18 -0800762 if (bb->fall_through) {
buzbee02031b12012-11-23 09:41:35 -0800763 cg->OpUnconditionalBranch(cu, &label_list[bb->fall_through->id]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700764 }
765 }
766 return false;
buzbeee3acd072012-02-25 17:03:10 -0800767}
768
buzbeefa57c472012-11-21 12:06:18 -0800769void SpecialMIR2LIR(CompilationUnit* cu, SpecialCaseHandler special_case)
buzbee16da88c2012-03-20 10:38:17 -0700770{
buzbee02031b12012-11-23 09:41:35 -0800771 Codegen* cg = cu->cg.get();
772 // Find the first DalvikByteCode block.
buzbeefa57c472012-11-21 12:06:18 -0800773 int num_reachable_blocks = cu->num_reachable_blocks;
774 const GrowableList *block_list = &cu->block_list;
Bill Buzbeea114add2012-05-03 15:00:40 -0700775 BasicBlock*bb = NULL;
buzbeefa57c472012-11-21 12:06:18 -0800776 for (int idx = 0; idx < num_reachable_blocks; idx++) {
777 int dfs_index = cu->dfs_order.elem_list[idx];
778 bb = reinterpret_cast<BasicBlock*>(GrowableListGetElement(block_list, dfs_index));
779 if (bb->block_type == kDalvikByteCode) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700780 break;
buzbee16da88c2012-03-20 10:38:17 -0700781 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700782 }
783 if (bb == NULL) {
784 return;
785 }
buzbeefa57c472012-11-21 12:06:18 -0800786 DCHECK_EQ(bb->start_offset, 0);
787 DCHECK(bb->first_mir_insn != NULL);
buzbee16da88c2012-03-20 10:38:17 -0700788
buzbee02031b12012-11-23 09:41:35 -0800789 // Get the first instruction.
buzbeefa57c472012-11-21 12:06:18 -0800790 MIR* mir = bb->first_mir_insn;
buzbee16da88c2012-03-20 10:38:17 -0700791
buzbee02031b12012-11-23 09:41:35 -0800792 // Free temp registers and reset redundant store tracking.
buzbeefa57c472012-11-21 12:06:18 -0800793 ResetRegPool(cu);
794 ResetDefTracking(cu);
795 ClobberAllRegs(cu);
buzbee16da88c2012-03-20 10:38:17 -0700796
buzbee02031b12012-11-23 09:41:35 -0800797 cg->GenSpecialCase(cu, bb, mir, special_case);
buzbee16da88c2012-03-20 10:38:17 -0700798}
799
buzbeefa57c472012-11-21 12:06:18 -0800800void MethodMIR2LIR(CompilationUnit* cu)
buzbeee3acd072012-02-25 17:03:10 -0800801{
buzbee02031b12012-11-23 09:41:35 -0800802 Codegen* cg = cu->cg.get();
803 // Hold the labels of each block.
buzbeefa57c472012-11-21 12:06:18 -0800804 cu->block_label_list =
805 static_cast<LIR*>(NewMem(cu, sizeof(LIR) * cu->num_blocks, true, kAllocLIR));
buzbeee3acd072012-02-25 17:03:10 -0800806
buzbeefa57c472012-11-21 12:06:18 -0800807 DataFlowAnalysisDispatcher(cu, MethodBlockCodeGen,
Bill Buzbeea114add2012-05-03 15:00:40 -0700808 kPreOrderDFSTraversal, false /* Iterative */);
Ian Rogersab2b55d2012-03-18 00:06:11 -0700809
buzbee02031b12012-11-23 09:41:35 -0800810 cg->HandleSuspendLaunchPads(cu);
buzbeee3acd072012-02-25 17:03:10 -0800811
buzbee02031b12012-11-23 09:41:35 -0800812 cg->HandleThrowLaunchPads(cu);
buzbeee3acd072012-02-25 17:03:10 -0800813
buzbee02031b12012-11-23 09:41:35 -0800814 cg->HandleIntrinsicLaunchPads(cu);
buzbeefc9e6fa2012-03-23 15:14:29 -0700815
buzbeefa57c472012-11-21 12:06:18 -0800816 if (!(cu->disable_opt & (1 << kSafeOptimizations))) {
817 RemoveRedundantBranches(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700818 }
buzbeee3acd072012-02-25 17:03:10 -0800819}
820
buzbeee3acd072012-02-25 17:03:10 -0800821} // namespace art