blob: 96de65e6444de979d556678d0625550aa4d05a04 [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
Brian Carlstrom641ce032013-01-31 15:21:37 -080019#include "compiler/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;
jeffhao1eab9582013-01-22 13:33:52 -080088
Bill Buzbeea114add2012-05-03 15:00:40 -070089 case Instruction::RETURN_VOID:
Ian Rogersfffdb022013-01-04 15:14:08 -080090 if (((cu->access_flags & kAccConstructor) != 0) &&
91 cu->compiler->RequiresConstructorBarrier(Thread::Current(), cu->dex_file,
92 cu->class_def_idx)) {
93 cg->GenMemBarrier(cu, kStoreStore);
94 }
buzbeefa57c472012-11-21 12:06:18 -080095 if (!(cu->attrs & METHOD_IS_LEAF)) {
buzbee02031b12012-11-23 09:41:35 -080096 cg->GenSuspendTest(cu, opt_flags);
Bill Buzbeea114add2012-05-03 15:00:40 -070097 }
98 break;
99
100 case Instruction::RETURN:
101 case Instruction::RETURN_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -0800102 if (!(cu->attrs & METHOD_IS_LEAF)) {
buzbee02031b12012-11-23 09:41:35 -0800103 cg->GenSuspendTest(cu, opt_flags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700104 }
buzbee02031b12012-11-23 09:41:35 -0800105 cg->StoreValue(cu, GetReturn(cu, cu->shorty[0] == 'F'), rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700106 break;
107
108 case Instruction::RETURN_WIDE:
buzbeefa57c472012-11-21 12:06:18 -0800109 if (!(cu->attrs & METHOD_IS_LEAF)) {
buzbee02031b12012-11-23 09:41:35 -0800110 cg->GenSuspendTest(cu, opt_flags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700111 }
buzbee02031b12012-11-23 09:41:35 -0800112 cg->StoreValueWide(cu, GetReturnWide(cu,
buzbeefa57c472012-11-21 12:06:18 -0800113 cu->shorty[0] == 'D'), rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700114 break;
115
116 case Instruction::MOVE_RESULT_WIDE:
buzbeefa57c472012-11-21 12:06:18 -0800117 if (opt_flags & MIR_INLINED)
buzbee02031b12012-11-23 09:41:35 -0800118 break; // Nop - combined w/ previous invoke.
119 cg->StoreValueWide(cu, rl_dest, GetReturnWide(cu, rl_dest.fp));
Bill Buzbeea114add2012-05-03 15:00:40 -0700120 break;
121
122 case Instruction::MOVE_RESULT:
123 case Instruction::MOVE_RESULT_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -0800124 if (opt_flags & MIR_INLINED)
buzbee02031b12012-11-23 09:41:35 -0800125 break; // Nop - combined w/ previous invoke.
126 cg->StoreValue(cu, rl_dest, GetReturn(cu, rl_dest.fp));
Bill Buzbeea114add2012-05-03 15:00:40 -0700127 break;
128
129 case Instruction::MOVE:
130 case Instruction::MOVE_OBJECT:
131 case Instruction::MOVE_16:
132 case Instruction::MOVE_OBJECT_16:
133 case Instruction::MOVE_FROM16:
134 case Instruction::MOVE_OBJECT_FROM16:
buzbee02031b12012-11-23 09:41:35 -0800135 cg->StoreValue(cu, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700136 break;
137
138 case Instruction::MOVE_WIDE:
139 case Instruction::MOVE_WIDE_16:
140 case Instruction::MOVE_WIDE_FROM16:
buzbee02031b12012-11-23 09:41:35 -0800141 cg->StoreValueWide(cu, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700142 break;
143
144 case Instruction::CONST:
145 case Instruction::CONST_4:
146 case Instruction::CONST_16:
buzbeefa57c472012-11-21 12:06:18 -0800147 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee02031b12012-11-23 09:41:35 -0800148 cg->LoadConstantNoClobber(cu, rl_result.low_reg, vB);
149 cg->StoreValue(cu, rl_dest, rl_result);
buzbee7da142f2012-11-29 16:33:42 -0800150 if (vB == 0) {
151 cg->Workaround7250540(cu, rl_dest, rl_result.low_reg);
152 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700153 break;
154
155 case Instruction::CONST_HIGH16:
buzbeefa57c472012-11-21 12:06:18 -0800156 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee02031b12012-11-23 09:41:35 -0800157 cg->LoadConstantNoClobber(cu, rl_result.low_reg, vB << 16);
158 cg->StoreValue(cu, rl_dest, rl_result);
buzbee7da142f2012-11-29 16:33:42 -0800159 if (vB == 0) {
160 cg->Workaround7250540(cu, rl_dest, rl_result.low_reg);
161 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700162 break;
163
164 case Instruction::CONST_WIDE_16:
165 case Instruction::CONST_WIDE_32:
buzbeefa57c472012-11-21 12:06:18 -0800166 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee4ef3e452012-12-14 13:35:28 -0800167 cg->LoadConstantWide(cu, rl_result.low_reg, rl_result.high_reg,
168 static_cast<int64_t>(static_cast<int32_t>(vB)));
buzbee02031b12012-11-23 09:41:35 -0800169 cg->StoreValueWide(cu, rl_dest, rl_result);
Bill Buzbeea114add2012-05-03 15:00:40 -0700170 break;
171
172 case Instruction::CONST_WIDE:
buzbeefa57c472012-11-21 12:06:18 -0800173 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee4ef3e452012-12-14 13:35:28 -0800174 cg->LoadConstantWide(cu, rl_result.low_reg, rl_result.high_reg, mir->dalvikInsn.vB_wide);
buzbee02031b12012-11-23 09:41:35 -0800175 cg->StoreValueWide(cu, rl_dest, rl_result);
Bill Buzbeea114add2012-05-03 15:00:40 -0700176 break;
177
178 case Instruction::CONST_WIDE_HIGH16:
buzbeefa57c472012-11-21 12:06:18 -0800179 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee4ef3e452012-12-14 13:35:28 -0800180 cg->LoadConstantWide(cu, rl_result.low_reg, rl_result.high_reg,
181 static_cast<int64_t>(vB) << 48);
buzbee02031b12012-11-23 09:41:35 -0800182 cg->StoreValueWide(cu, rl_dest, rl_result);
Bill Buzbeea114add2012-05-03 15:00:40 -0700183 break;
184
185 case Instruction::MONITOR_ENTER:
buzbee02031b12012-11-23 09:41:35 -0800186 cg->GenMonitorEnter(cu, opt_flags, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700187 break;
188
189 case Instruction::MONITOR_EXIT:
buzbee02031b12012-11-23 09:41:35 -0800190 cg->GenMonitorExit(cu, opt_flags, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700191 break;
192
193 case Instruction::CHECK_CAST:
buzbee02031b12012-11-23 09:41:35 -0800194 cg->GenCheckCast(cu, vB, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700195 break;
196
197 case Instruction::INSTANCE_OF:
buzbee02031b12012-11-23 09:41:35 -0800198 cg->GenInstanceof(cu, vC, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700199 break;
200
201 case Instruction::NEW_INSTANCE:
buzbee02031b12012-11-23 09:41:35 -0800202 cg->GenNewInstance(cu, vB, rl_dest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700203 break;
204
205 case Instruction::THROW:
buzbee02031b12012-11-23 09:41:35 -0800206 cg->GenThrow(cu, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700207 break;
208
Bill Buzbeea114add2012-05-03 15:00:40 -0700209 case Instruction::ARRAY_LENGTH:
buzbeefa57c472012-11-21 12:06:18 -0800210 int len_offset;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800211 len_offset = mirror::Array::LengthOffset().Int32Value();
buzbee02031b12012-11-23 09:41:35 -0800212 rl_src[0] = cg->LoadValue(cu, rl_src[0], kCoreReg);
213 cg->GenNullCheck(cu, rl_src[0].s_reg_low, rl_src[0].low_reg, opt_flags);
buzbeefa57c472012-11-21 12:06:18 -0800214 rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
buzbee02031b12012-11-23 09:41:35 -0800215 cg->LoadWordDisp(cu, rl_src[0].low_reg, len_offset, rl_result.low_reg);
216 cg->StoreValue(cu, rl_dest, rl_result);
Bill Buzbeea114add2012-05-03 15:00:40 -0700217 break;
218
219 case Instruction::CONST_STRING:
220 case Instruction::CONST_STRING_JUMBO:
buzbee02031b12012-11-23 09:41:35 -0800221 cg->GenConstString(cu, vB, rl_dest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700222 break;
223
224 case Instruction::CONST_CLASS:
buzbee02031b12012-11-23 09:41:35 -0800225 cg->GenConstClass(cu, vB, rl_dest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700226 break;
227
228 case Instruction::FILL_ARRAY_DATA:
buzbee02031b12012-11-23 09:41:35 -0800229 cg->GenFillArrayData(cu, vB, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700230 break;
231
232 case Instruction::FILLED_NEW_ARRAY:
buzbee02031b12012-11-23 09:41:35 -0800233 cg->GenFilledNewArray(cu, cg->NewMemCallInfo(cu, bb, mir, kStatic,
buzbee3b3dbdd2012-06-13 13:39:34 -0700234 false /* not range */));
Bill Buzbeea114add2012-05-03 15:00:40 -0700235 break;
236
237 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800238 cg->GenFilledNewArray(cu, cg->NewMemCallInfo(cu, bb, mir, kStatic,
buzbee3b3dbdd2012-06-13 13:39:34 -0700239 true /* range */));
Bill Buzbeea114add2012-05-03 15:00:40 -0700240 break;
241
242 case Instruction::NEW_ARRAY:
buzbee02031b12012-11-23 09:41:35 -0800243 cg->GenNewArray(cu, vC, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700244 break;
245
246 case Instruction::GOTO:
247 case Instruction::GOTO_16:
248 case Instruction::GOTO_32:
buzbeefa57c472012-11-21 12:06:18 -0800249 if (bb->taken->start_offset <= mir->offset) {
buzbee02031b12012-11-23 09:41:35 -0800250 cg->GenSuspendTestAndBranch(cu, opt_flags, &label_list[bb->taken->id]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700251 } else {
buzbee02031b12012-11-23 09:41:35 -0800252 cg->OpUnconditionalBranch(cu, &label_list[bb->taken->id]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700253 }
254 break;
255
256 case Instruction::PACKED_SWITCH:
buzbee02031b12012-11-23 09:41:35 -0800257 cg->GenPackedSwitch(cu, vB, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700258 break;
259
260 case Instruction::SPARSE_SWITCH:
buzbee02031b12012-11-23 09:41:35 -0800261 cg->GenSparseSwitch(cu, vB, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700262 break;
263
264 case Instruction::CMPL_FLOAT:
265 case Instruction::CMPG_FLOAT:
266 case Instruction::CMPL_DOUBLE:
267 case Instruction::CMPG_DOUBLE:
buzbee02031b12012-11-23 09:41:35 -0800268 res = cg->GenCmpFP(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700269 break;
270
271 case Instruction::CMP_LONG:
buzbee02031b12012-11-23 09:41:35 -0800272 cg->GenCmpLong(cu, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700273 break;
274
275 case Instruction::IF_EQ:
276 case Instruction::IF_NE:
277 case Instruction::IF_LT:
278 case Instruction::IF_GE:
279 case Instruction::IF_GT:
280 case Instruction::IF_LE: {
buzbeefa57c472012-11-21 12:06:18 -0800281 LIR* taken = &label_list[bb->taken->id];
282 LIR* fall_through = &label_list[bb->fall_through->id];
283 bool backward_branch;
284 backward_branch = (bb->taken->start_offset <= mir->offset);
buzbeee6285f92012-12-06 15:57:46 -0800285 // Result known at compile time?
286 if (rl_src[0].is_const && rl_src[1].is_const) {
287 bool is_taken = EvaluateBranch(opcode, cu->constant_values[rl_src[0].orig_sreg],
288 cu->constant_values[rl_src[1].orig_sreg]);
289 if (is_taken && backward_branch) {
290 cg->GenSuspendTest(cu, opt_flags);
291 }
292 int id = is_taken ? bb->taken->id : bb->fall_through->id;
293 cg->OpUnconditionalBranch(cu, &label_list[id]);
294 } else {
295 if (backward_branch) {
296 cg->GenSuspendTest(cu, opt_flags);
297 }
298 cg->GenCompareAndBranch(cu, opcode, rl_src[0], rl_src[1], taken,
299 fall_through);
Bill Buzbeea114add2012-05-03 15:00:40 -0700300 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700301 break;
302 }
303
304 case Instruction::IF_EQZ:
305 case Instruction::IF_NEZ:
306 case Instruction::IF_LTZ:
307 case Instruction::IF_GEZ:
308 case Instruction::IF_GTZ:
309 case Instruction::IF_LEZ: {
buzbeefa57c472012-11-21 12:06:18 -0800310 LIR* taken = &label_list[bb->taken->id];
311 LIR* fall_through = &label_list[bb->fall_through->id];
312 bool backward_branch;
313 backward_branch = (bb->taken->start_offset <= mir->offset);
buzbeee6285f92012-12-06 15:57:46 -0800314 // Result known at compile time?
315 if (rl_src[0].is_const) {
316 bool is_taken = EvaluateBranch(opcode, cu->constant_values[rl_src[0].orig_sreg], 0);
317 if (is_taken && backward_branch) {
318 cg->GenSuspendTest(cu, opt_flags);
319 }
320 int id = is_taken ? bb->taken->id : bb->fall_through->id;
321 cg->OpUnconditionalBranch(cu, &label_list[id]);
322 } else {
323 if (backward_branch) {
324 cg->GenSuspendTest(cu, opt_flags);
325 }
326 cg->GenCompareZeroAndBranch(cu, opcode, rl_src[0], taken, fall_through);
Bill Buzbeea114add2012-05-03 15:00:40 -0700327 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700328 break;
329 }
330
331 case Instruction::AGET_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800332 cg->GenArrayGet(cu, opt_flags, kLong, rl_src[0], rl_src[1], rl_dest, 3);
Bill Buzbeea114add2012-05-03 15:00:40 -0700333 break;
334 case Instruction::AGET:
335 case Instruction::AGET_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800336 cg->GenArrayGet(cu, opt_flags, kWord, rl_src[0], rl_src[1], rl_dest, 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700337 break;
338 case Instruction::AGET_BOOLEAN:
buzbee02031b12012-11-23 09:41:35 -0800339 cg->GenArrayGet(cu, opt_flags, kUnsignedByte, rl_src[0], rl_src[1], rl_dest, 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700340 break;
341 case Instruction::AGET_BYTE:
buzbee02031b12012-11-23 09:41:35 -0800342 cg->GenArrayGet(cu, opt_flags, kSignedByte, rl_src[0], rl_src[1], rl_dest, 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700343 break;
344 case Instruction::AGET_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800345 cg->GenArrayGet(cu, opt_flags, kUnsignedHalf, rl_src[0], rl_src[1], rl_dest, 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700346 break;
347 case Instruction::AGET_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800348 cg->GenArrayGet(cu, opt_flags, kSignedHalf, rl_src[0], rl_src[1], rl_dest, 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700349 break;
350 case Instruction::APUT_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800351 cg->GenArrayPut(cu, opt_flags, kLong, rl_src[1], rl_src[2], rl_src[0], 3);
Bill Buzbeea114add2012-05-03 15:00:40 -0700352 break;
353 case Instruction::APUT:
buzbee02031b12012-11-23 09:41:35 -0800354 cg->GenArrayPut(cu, opt_flags, kWord, rl_src[1], rl_src[2], rl_src[0], 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700355 break;
356 case Instruction::APUT_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800357 cg->GenArrayObjPut(cu, opt_flags, rl_src[1], rl_src[2], rl_src[0], 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700358 break;
359 case Instruction::APUT_SHORT:
360 case Instruction::APUT_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800361 cg->GenArrayPut(cu, opt_flags, kUnsignedHalf, rl_src[1], rl_src[2], rl_src[0], 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700362 break;
363 case Instruction::APUT_BYTE:
364 case Instruction::APUT_BOOLEAN:
buzbee02031b12012-11-23 09:41:35 -0800365 cg->GenArrayPut(cu, opt_flags, kUnsignedByte, rl_src[1], rl_src[2],
buzbeefa57c472012-11-21 12:06:18 -0800366 rl_src[0], 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700367 break;
368
369 case Instruction::IGET_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800370 cg->GenIGet(cu, vC, opt_flags, kWord, rl_dest, rl_src[0], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700371 break;
372
373 case Instruction::IGET_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800374 cg->GenIGet(cu, vC, opt_flags, kLong, rl_dest, rl_src[0], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700375 break;
376
377 case Instruction::IGET:
buzbee02031b12012-11-23 09:41:35 -0800378 cg->GenIGet(cu, vC, opt_flags, kWord, rl_dest, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700379 break;
380
381 case Instruction::IGET_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800382 cg->GenIGet(cu, vC, opt_flags, kUnsignedHalf, rl_dest, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700383 break;
384
385 case Instruction::IGET_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800386 cg->GenIGet(cu, vC, opt_flags, kSignedHalf, rl_dest, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700387 break;
388
389 case Instruction::IGET_BOOLEAN:
390 case Instruction::IGET_BYTE:
buzbee02031b12012-11-23 09:41:35 -0800391 cg->GenIGet(cu, vC, opt_flags, kUnsignedByte, rl_dest, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700392 break;
393
394 case Instruction::IPUT_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800395 cg->GenIPut(cu, vC, opt_flags, kLong, rl_src[0], rl_src[1], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700396 break;
397
398 case Instruction::IPUT_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800399 cg->GenIPut(cu, vC, opt_flags, kWord, rl_src[0], rl_src[1], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700400 break;
401
402 case Instruction::IPUT:
buzbee02031b12012-11-23 09:41:35 -0800403 cg->GenIPut(cu, vC, opt_flags, kWord, rl_src[0], rl_src[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700404 break;
405
406 case Instruction::IPUT_BOOLEAN:
407 case Instruction::IPUT_BYTE:
buzbee02031b12012-11-23 09:41:35 -0800408 cg->GenIPut(cu, vC, opt_flags, kUnsignedByte, rl_src[0], rl_src[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700409 break;
410
411 case Instruction::IPUT_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800412 cg->GenIPut(cu, vC, opt_flags, kUnsignedHalf, rl_src[0], rl_src[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700413 break;
414
415 case Instruction::IPUT_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800416 cg->GenIPut(cu, vC, opt_flags, kSignedHalf, rl_src[0], rl_src[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700417 break;
418
419 case Instruction::SGET_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800420 cg->GenSget(cu, vB, rl_dest, false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700421 break;
422 case Instruction::SGET:
423 case Instruction::SGET_BOOLEAN:
424 case Instruction::SGET_BYTE:
425 case Instruction::SGET_CHAR:
426 case Instruction::SGET_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800427 cg->GenSget(cu, vB, rl_dest, false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700428 break;
429
430 case Instruction::SGET_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800431 cg->GenSget(cu, vB, rl_dest, true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700432 break;
433
434 case Instruction::SPUT_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800435 cg->GenSput(cu, vB, rl_src[0], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700436 break;
437
438 case Instruction::SPUT:
439 case Instruction::SPUT_BOOLEAN:
440 case Instruction::SPUT_BYTE:
441 case Instruction::SPUT_CHAR:
442 case Instruction::SPUT_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800443 cg->GenSput(cu, vB, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700444 break;
445
446 case Instruction::SPUT_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800447 cg->GenSput(cu, vB, rl_src[0], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700448 break;
449
450 case Instruction::INVOKE_STATIC_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800451 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kStatic, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700452 break;
453 case Instruction::INVOKE_STATIC:
buzbee02031b12012-11-23 09:41:35 -0800454 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kStatic, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700455 break;
456
457 case Instruction::INVOKE_DIRECT:
buzbee02031b12012-11-23 09:41:35 -0800458 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kDirect, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700459 break;
460 case Instruction::INVOKE_DIRECT_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800461 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kDirect, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700462 break;
463
464 case Instruction::INVOKE_VIRTUAL:
buzbee02031b12012-11-23 09:41:35 -0800465 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kVirtual, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700466 break;
467 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800468 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kVirtual, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700469 break;
470
471 case Instruction::INVOKE_SUPER:
buzbee02031b12012-11-23 09:41:35 -0800472 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kSuper, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700473 break;
474 case Instruction::INVOKE_SUPER_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800475 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kSuper, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700476 break;
477
478 case Instruction::INVOKE_INTERFACE:
buzbee02031b12012-11-23 09:41:35 -0800479 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kInterface, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700480 break;
481 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800482 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kInterface, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700483 break;
484
485 case Instruction::NEG_INT:
486 case Instruction::NOT_INT:
buzbee02031b12012-11-23 09:41:35 -0800487 res = cg->GenArithOpInt(cu, opcode, rl_dest, rl_src[0], rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700488 break;
489
490 case Instruction::NEG_LONG:
491 case Instruction::NOT_LONG:
buzbee02031b12012-11-23 09:41:35 -0800492 res = cg->GenArithOpLong(cu, opcode, rl_dest, rl_src[0], rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700493 break;
494
495 case Instruction::NEG_FLOAT:
buzbee02031b12012-11-23 09:41:35 -0800496 res = cg->GenArithOpFloat(cu, opcode, rl_dest, rl_src[0], rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700497 break;
498
499 case Instruction::NEG_DOUBLE:
buzbee02031b12012-11-23 09:41:35 -0800500 res = cg->GenArithOpDouble(cu, opcode, rl_dest, rl_src[0], rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700501 break;
502
503 case Instruction::INT_TO_LONG:
buzbee02031b12012-11-23 09:41:35 -0800504 cg->GenIntToLong(cu, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700505 break;
506
507 case Instruction::LONG_TO_INT:
buzbeefa57c472012-11-21 12:06:18 -0800508 rl_src[0] = UpdateLocWide(cu, rl_src[0]);
509 rl_src[0] = WideToNarrow(cu, rl_src[0]);
buzbee02031b12012-11-23 09:41:35 -0800510 cg->StoreValue(cu, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700511 break;
512
513 case Instruction::INT_TO_BYTE:
514 case Instruction::INT_TO_SHORT:
515 case Instruction::INT_TO_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800516 cg->GenIntNarrowing(cu, opcode, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700517 break;
518
519 case Instruction::INT_TO_FLOAT:
520 case Instruction::INT_TO_DOUBLE:
521 case Instruction::LONG_TO_FLOAT:
522 case Instruction::LONG_TO_DOUBLE:
523 case Instruction::FLOAT_TO_INT:
524 case Instruction::FLOAT_TO_LONG:
525 case Instruction::FLOAT_TO_DOUBLE:
526 case Instruction::DOUBLE_TO_INT:
527 case Instruction::DOUBLE_TO_LONG:
528 case Instruction::DOUBLE_TO_FLOAT:
buzbee02031b12012-11-23 09:41:35 -0800529 cg->GenConversion(cu, opcode, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700530 break;
531
buzbeee6285f92012-12-06 15:57:46 -0800532
Bill Buzbeea114add2012-05-03 15:00:40 -0700533 case Instruction::ADD_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700534 case Instruction::ADD_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800535 case Instruction::MUL_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700536 case Instruction::MUL_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800537 case Instruction::AND_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700538 case Instruction::AND_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800539 case Instruction::OR_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700540 case Instruction::OR_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800541 case Instruction::XOR_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700542 case Instruction::XOR_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800543 if (rl_src[0].is_const &&
buzbee4ef3e452012-12-14 13:35:28 -0800544 cu->cg->InexpensiveConstantInt(ConstantValue(cu, rl_src[0]))) {
buzbeee6285f92012-12-06 15:57:46 -0800545 cg->GenArithOpIntLit(cu, opcode, rl_dest, rl_src[1],
546 cu->constant_values[rl_src[0].orig_sreg]);
547 } else if (rl_src[1].is_const &&
buzbee4ef3e452012-12-14 13:35:28 -0800548 cu->cg->InexpensiveConstantInt(ConstantValue(cu, rl_src[1]))) {
buzbeee6285f92012-12-06 15:57:46 -0800549 cg->GenArithOpIntLit(cu, opcode, rl_dest, rl_src[0],
550 cu->constant_values[rl_src[1].orig_sreg]);
551 } else {
552 cg->GenArithOpInt(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
553 }
554 break;
555
556 case Instruction::SUB_INT:
557 case Instruction::SUB_INT_2ADDR:
558 case Instruction::DIV_INT:
559 case Instruction::DIV_INT_2ADDR:
560 case Instruction::REM_INT:
561 case Instruction::REM_INT_2ADDR:
562 case Instruction::SHL_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700563 case Instruction::SHL_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800564 case Instruction::SHR_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700565 case Instruction::SHR_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800566 case Instruction::USHR_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700567 case Instruction::USHR_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800568 if (rl_src[1].is_const &&
buzbee4ef3e452012-12-14 13:35:28 -0800569 cu->cg->InexpensiveConstantInt(ConstantValue(cu, rl_src[1]))) {
570 cg->GenArithOpIntLit(cu, opcode, rl_dest, rl_src[0], ConstantValue(cu, rl_src[1]));
buzbeee6285f92012-12-06 15:57:46 -0800571 } else {
572 cg->GenArithOpInt(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
573 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700574 break;
575
576 case Instruction::ADD_LONG:
577 case Instruction::SUB_LONG:
Bill Buzbeea114add2012-05-03 15:00:40 -0700578 case Instruction::AND_LONG:
579 case Instruction::OR_LONG:
580 case Instruction::XOR_LONG:
581 case Instruction::ADD_LONG_2ADDR:
582 case Instruction::SUB_LONG_2ADDR:
Bill Buzbeea114add2012-05-03 15:00:40 -0700583 case Instruction::AND_LONG_2ADDR:
584 case Instruction::OR_LONG_2ADDR:
585 case Instruction::XOR_LONG_2ADDR:
buzbee4ef3e452012-12-14 13:35:28 -0800586 if (rl_src[0].is_const || rl_src[1].is_const) {
587 cg->GenArithImmOpLong(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
588 break;
589 }
590 // Note: intentional fallthrough.
591
592 case Instruction::MUL_LONG:
593 case Instruction::DIV_LONG:
594 case Instruction::REM_LONG:
595 case Instruction::MUL_LONG_2ADDR:
596 case Instruction::DIV_LONG_2ADDR:
597 case Instruction::REM_LONG_2ADDR:
buzbee02031b12012-11-23 09:41:35 -0800598 cg->GenArithOpLong(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700599 break;
600
601 case Instruction::SHL_LONG:
602 case Instruction::SHR_LONG:
603 case Instruction::USHR_LONG:
604 case Instruction::SHL_LONG_2ADDR:
605 case Instruction::SHR_LONG_2ADDR:
606 case Instruction::USHR_LONG_2ADDR:
buzbee4ef3e452012-12-14 13:35:28 -0800607 if (rl_src[1].is_const) {
608 cg->GenShiftImmOpLong(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
609 } else {
610 cg->GenShiftOpLong(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
611 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700612 break;
613
614 case Instruction::ADD_FLOAT:
615 case Instruction::SUB_FLOAT:
616 case Instruction::MUL_FLOAT:
617 case Instruction::DIV_FLOAT:
618 case Instruction::REM_FLOAT:
619 case Instruction::ADD_FLOAT_2ADDR:
620 case Instruction::SUB_FLOAT_2ADDR:
621 case Instruction::MUL_FLOAT_2ADDR:
622 case Instruction::DIV_FLOAT_2ADDR:
623 case Instruction::REM_FLOAT_2ADDR:
buzbee02031b12012-11-23 09:41:35 -0800624 cg->GenArithOpFloat(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700625 break;
626
627 case Instruction::ADD_DOUBLE:
628 case Instruction::SUB_DOUBLE:
629 case Instruction::MUL_DOUBLE:
630 case Instruction::DIV_DOUBLE:
631 case Instruction::REM_DOUBLE:
632 case Instruction::ADD_DOUBLE_2ADDR:
633 case Instruction::SUB_DOUBLE_2ADDR:
634 case Instruction::MUL_DOUBLE_2ADDR:
635 case Instruction::DIV_DOUBLE_2ADDR:
636 case Instruction::REM_DOUBLE_2ADDR:
buzbee02031b12012-11-23 09:41:35 -0800637 cg->GenArithOpDouble(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700638 break;
639
640 case Instruction::RSUB_INT:
641 case Instruction::ADD_INT_LIT16:
642 case Instruction::MUL_INT_LIT16:
643 case Instruction::DIV_INT_LIT16:
644 case Instruction::REM_INT_LIT16:
645 case Instruction::AND_INT_LIT16:
646 case Instruction::OR_INT_LIT16:
647 case Instruction::XOR_INT_LIT16:
648 case Instruction::ADD_INT_LIT8:
649 case Instruction::RSUB_INT_LIT8:
650 case Instruction::MUL_INT_LIT8:
651 case Instruction::DIV_INT_LIT8:
652 case Instruction::REM_INT_LIT8:
653 case Instruction::AND_INT_LIT8:
654 case Instruction::OR_INT_LIT8:
655 case Instruction::XOR_INT_LIT8:
656 case Instruction::SHL_INT_LIT8:
657 case Instruction::SHR_INT_LIT8:
658 case Instruction::USHR_INT_LIT8:
buzbee02031b12012-11-23 09:41:35 -0800659 cg->GenArithOpIntLit(cu, opcode, rl_dest, rl_src[0], vC);
Bill Buzbeea114add2012-05-03 15:00:40 -0700660 break;
661
662 default:
663 res = true;
664 }
665 return res;
buzbeee3acd072012-02-25 17:03:10 -0800666}
667
buzbeea169e1d2012-12-05 14:26:44 -0800668// Process extended MIR instructions
buzbeefa57c472012-11-21 12:06:18 -0800669static void HandleExtendedMethodMIR(CompilationUnit* cu, BasicBlock* bb, MIR* mir)
buzbeee3acd072012-02-25 17:03:10 -0800670{
buzbee02031b12012-11-23 09:41:35 -0800671 Codegen* cg = cu->cg.get();
buzbeecbd6d442012-11-17 14:11:25 -0800672 switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700673 case kMirOpCopy: {
buzbeefa57c472012-11-21 12:06:18 -0800674 RegLocation rl_src = GetSrc(cu, mir, 0);
675 RegLocation rl_dest = GetDest(cu, mir);
buzbee02031b12012-11-23 09:41:35 -0800676 cg->StoreValue(cu, rl_dest, rl_src);
Bill Buzbeea114add2012-05-03 15:00:40 -0700677 break;
678 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700679 case kMirOpFusedCmplFloat:
buzbee02031b12012-11-23 09:41:35 -0800680 cg->GenFusedFPCmpBranch(cu, bb, mir, false /*gt bias*/, false /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700681 break;
682 case kMirOpFusedCmpgFloat:
buzbee02031b12012-11-23 09:41:35 -0800683 cg->GenFusedFPCmpBranch(cu, bb, mir, true /*gt bias*/, false /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700684 break;
685 case kMirOpFusedCmplDouble:
buzbee02031b12012-11-23 09:41:35 -0800686 cg->GenFusedFPCmpBranch(cu, bb, mir, false /*gt bias*/, true /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700687 break;
688 case kMirOpFusedCmpgDouble:
buzbee02031b12012-11-23 09:41:35 -0800689 cg->GenFusedFPCmpBranch(cu, bb, mir, true /*gt bias*/, true /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700690 break;
691 case kMirOpFusedCmpLong:
buzbee02031b12012-11-23 09:41:35 -0800692 cg->GenFusedLongCmpBranch(cu, bb, mir);
Bill Buzbeea114add2012-05-03 15:00:40 -0700693 break;
Bill Buzbeea114add2012-05-03 15:00:40 -0700694 default:
695 break;
696 }
buzbeee3acd072012-02-25 17:03:10 -0800697}
698
buzbee02031b12012-11-23 09:41:35 -0800699// Handle the content in each basic block.
buzbeefa57c472012-11-21 12:06:18 -0800700static bool MethodBlockCodeGen(CompilationUnit* cu, BasicBlock* bb)
buzbeee3acd072012-02-25 17:03:10 -0800701{
buzbeefa57c472012-11-21 12:06:18 -0800702 if (bb->block_type == kDead) return false;
buzbee02031b12012-11-23 09:41:35 -0800703 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -0800704 cu->current_dalvik_offset = bb->start_offset;
Bill Buzbeea114add2012-05-03 15:00:40 -0700705 MIR* mir;
buzbeefa57c472012-11-21 12:06:18 -0800706 LIR* label_list = cu->block_label_list;
707 int block_id = bb->id;
buzbeee3acd072012-02-25 17:03:10 -0800708
buzbeefa57c472012-11-21 12:06:18 -0800709 cu->cur_block = bb;
710 label_list[block_id].operands[0] = bb->start_offset;
buzbeee3acd072012-02-25 17:03:10 -0800711
buzbee02031b12012-11-23 09:41:35 -0800712 // Insert the block label.
buzbeefa57c472012-11-21 12:06:18 -0800713 label_list[block_id].opcode = kPseudoNormalBlockLabel;
714 AppendLIR(cu, &label_list[block_id]);
buzbeee3acd072012-02-25 17:03:10 -0800715
buzbeefa57c472012-11-21 12:06:18 -0800716 LIR* head_lir = NULL;
buzbee8320f382012-09-11 16:29:42 -0700717
buzbee02031b12012-11-23 09:41:35 -0800718 // If this is a catch block, export the start address.
buzbeefa57c472012-11-21 12:06:18 -0800719 if (bb->catch_entry) {
720 head_lir = NewLIR0(cu, kPseudoExportedPC);
buzbee8320f382012-09-11 16:29:42 -0700721 }
722
buzbee02031b12012-11-23 09:41:35 -0800723 // Free temp registers and reset redundant store tracking.
buzbeefa57c472012-11-21 12:06:18 -0800724 ResetRegPool(cu);
725 ResetDefTracking(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700726
buzbeefa57c472012-11-21 12:06:18 -0800727 ClobberAllRegs(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700728
buzbeefa57c472012-11-21 12:06:18 -0800729 if (bb->block_type == kEntryBlock) {
730 int start_vreg = cu->num_dalvik_registers - cu->num_ins;
buzbee02031b12012-11-23 09:41:35 -0800731 cg->GenEntrySequence(cu, &cu->reg_location[start_vreg],
732 cu->reg_location[cu->method_sreg]);
buzbeefa57c472012-11-21 12:06:18 -0800733 } else if (bb->block_type == kExitBlock) {
buzbee02031b12012-11-23 09:41:35 -0800734 cg->GenExitSequence(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700735 }
736
buzbee28c9a832012-11-21 15:39:13 -0800737 for (mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
buzbeefa57c472012-11-21 12:06:18 -0800738 ResetRegPool(cu);
739 if (cu->disable_opt & (1 << kTrackLiveTemps)) {
740 ClobberAllRegs(cu);
buzbeee1965672012-03-11 18:39:19 -0700741 }
742
buzbeefa57c472012-11-21 12:06:18 -0800743 if (cu->disable_opt & (1 << kSuppressLoads)) {
744 ResetDefTracking(cu);
buzbeee3acd072012-02-25 17:03:10 -0800745 }
746
buzbee3d661942012-03-14 17:37:27 -0700747#ifndef NDEBUG
buzbee02031b12012-11-23 09:41:35 -0800748 // Reset temp tracking sanity check.
buzbeefa57c472012-11-21 12:06:18 -0800749 cu->live_sreg = INVALID_SREG;
buzbee3d661942012-03-14 17:37:27 -0700750#endif
751
buzbeefa57c472012-11-21 12:06:18 -0800752 cu->current_dalvik_offset = mir->offset;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700753 int opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -0800754 LIR* boundary_lir;
buzbeee3acd072012-02-25 17:03:10 -0800755
buzbee02031b12012-11-23 09:41:35 -0800756 // Mark the beginning of a Dalvik instruction for line tracking.
buzbeefa57c472012-11-21 12:06:18 -0800757 char* inst_str = cu->verbose ?
buzbeea169e1d2012-12-05 14:26:44 -0800758 GetDalvikDisassembly(cu, mir) : NULL;
buzbeefa57c472012-11-21 12:06:18 -0800759 boundary_lir = MarkBoundary(cu, mir->offset, inst_str);
buzbee02031b12012-11-23 09:41:35 -0800760 // Remember the first LIR for this block.
buzbeefa57c472012-11-21 12:06:18 -0800761 if (head_lir == NULL) {
762 head_lir = boundary_lir;
buzbee02031b12012-11-23 09:41:35 -0800763 // Set the first boundary_lir as a scheduling barrier.
buzbeefa57c472012-11-21 12:06:18 -0800764 head_lir->def_mask = ENCODE_ALL;
buzbeee3acd072012-02-25 17:03:10 -0800765 }
766
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700767 if (opcode == kMirOpCheck) {
768 // Combine check and work halves of throwing instruction.
buzbeefa57c472012-11-21 12:06:18 -0800769 MIR* work_half = mir->meta.throw_insn;
770 mir->dalvikInsn.opcode = work_half->dalvikInsn.opcode;
771 opcode = work_half->dalvikInsn.opcode;
772 SSARepresentation* ssa_rep = work_half->ssa_rep;
773 work_half->ssa_rep = mir->ssa_rep;
774 mir->ssa_rep = ssa_rep;
buzbeea169e1d2012-12-05 14:26:44 -0800775 work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpCheckPart2);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700776 }
777
778 if (opcode >= kMirOpFirst) {
buzbeefa57c472012-11-21 12:06:18 -0800779 HandleExtendedMethodMIR(cu, bb, mir);
Bill Buzbeea114add2012-05-03 15:00:40 -0700780 continue;
781 }
782
buzbeefa57c472012-11-21 12:06:18 -0800783 bool not_handled = CompileDalvikInstruction(cu, mir, bb, label_list);
784 if (not_handled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700785 LOG(FATAL) << StringPrintf("%#06x: Opcode %#x (%s)",
786 mir->offset, opcode,
787 Instruction::Name(mir->dalvikInsn.opcode));
Bill Buzbeea114add2012-05-03 15:00:40 -0700788 }
789 }
790
buzbeefa57c472012-11-21 12:06:18 -0800791 if (head_lir) {
buzbee02031b12012-11-23 09:41:35 -0800792 // Eliminate redundant loads/stores and delay stores into later slots.
buzbeefa57c472012-11-21 12:06:18 -0800793 ApplyLocalOptimizations(cu, head_lir, cu->last_lir_insn);
Bill Buzbeea114add2012-05-03 15:00:40 -0700794
buzbee02031b12012-11-23 09:41:35 -0800795 // Generate an unconditional branch to the fallthrough block.
buzbeefa57c472012-11-21 12:06:18 -0800796 if (bb->fall_through) {
buzbee02031b12012-11-23 09:41:35 -0800797 cg->OpUnconditionalBranch(cu, &label_list[bb->fall_through->id]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700798 }
799 }
800 return false;
buzbeee3acd072012-02-25 17:03:10 -0800801}
802
buzbeefa57c472012-11-21 12:06:18 -0800803void SpecialMIR2LIR(CompilationUnit* cu, SpecialCaseHandler special_case)
buzbee16da88c2012-03-20 10:38:17 -0700804{
buzbee02031b12012-11-23 09:41:35 -0800805 Codegen* cg = cu->cg.get();
806 // Find the first DalvikByteCode block.
buzbeefa57c472012-11-21 12:06:18 -0800807 int num_reachable_blocks = cu->num_reachable_blocks;
808 const GrowableList *block_list = &cu->block_list;
Bill Buzbeea114add2012-05-03 15:00:40 -0700809 BasicBlock*bb = NULL;
buzbeefa57c472012-11-21 12:06:18 -0800810 for (int idx = 0; idx < num_reachable_blocks; idx++) {
811 int dfs_index = cu->dfs_order.elem_list[idx];
812 bb = reinterpret_cast<BasicBlock*>(GrowableListGetElement(block_list, dfs_index));
813 if (bb->block_type == kDalvikByteCode) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700814 break;
buzbee16da88c2012-03-20 10:38:17 -0700815 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700816 }
817 if (bb == NULL) {
818 return;
819 }
buzbeefa57c472012-11-21 12:06:18 -0800820 DCHECK_EQ(bb->start_offset, 0);
821 DCHECK(bb->first_mir_insn != NULL);
buzbee16da88c2012-03-20 10:38:17 -0700822
buzbee02031b12012-11-23 09:41:35 -0800823 // Get the first instruction.
buzbeefa57c472012-11-21 12:06:18 -0800824 MIR* mir = bb->first_mir_insn;
buzbee16da88c2012-03-20 10:38:17 -0700825
buzbee02031b12012-11-23 09:41:35 -0800826 // Free temp registers and reset redundant store tracking.
buzbeefa57c472012-11-21 12:06:18 -0800827 ResetRegPool(cu);
828 ResetDefTracking(cu);
829 ClobberAllRegs(cu);
buzbee16da88c2012-03-20 10:38:17 -0700830
buzbee02031b12012-11-23 09:41:35 -0800831 cg->GenSpecialCase(cu, bb, mir, special_case);
buzbee16da88c2012-03-20 10:38:17 -0700832}
833
buzbeefa57c472012-11-21 12:06:18 -0800834void MethodMIR2LIR(CompilationUnit* cu)
buzbeee3acd072012-02-25 17:03:10 -0800835{
buzbee02031b12012-11-23 09:41:35 -0800836 Codegen* cg = cu->cg.get();
837 // Hold the labels of each block.
buzbeefa57c472012-11-21 12:06:18 -0800838 cu->block_label_list =
839 static_cast<LIR*>(NewMem(cu, sizeof(LIR) * cu->num_blocks, true, kAllocLIR));
buzbeee3acd072012-02-25 17:03:10 -0800840
buzbeefa57c472012-11-21 12:06:18 -0800841 DataFlowAnalysisDispatcher(cu, MethodBlockCodeGen,
Bill Buzbeea114add2012-05-03 15:00:40 -0700842 kPreOrderDFSTraversal, false /* Iterative */);
Ian Rogersab2b55d2012-03-18 00:06:11 -0700843
buzbee02031b12012-11-23 09:41:35 -0800844 cg->HandleSuspendLaunchPads(cu);
buzbeee3acd072012-02-25 17:03:10 -0800845
buzbee02031b12012-11-23 09:41:35 -0800846 cg->HandleThrowLaunchPads(cu);
buzbeee3acd072012-02-25 17:03:10 -0800847
buzbee02031b12012-11-23 09:41:35 -0800848 cg->HandleIntrinsicLaunchPads(cu);
buzbeefc9e6fa2012-03-23 15:14:29 -0700849
buzbeefa57c472012-11-21 12:06:18 -0800850 if (!(cu->disable_opt & (1 << kSafeOptimizations))) {
851 RemoveRedundantBranches(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700852 }
buzbeee3acd072012-02-25 17:03:10 -0800853}
854
buzbeee3acd072012-02-25 17:03:10 -0800855} // namespace art