blob: 1d64661c5dea09fc542a6b0c69b7d76565a6300a [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:
Ian Rogersfffdb022013-01-04 15:14:08 -080089 if (((cu->access_flags & kAccConstructor) != 0) &&
90 cu->compiler->RequiresConstructorBarrier(Thread::Current(), cu->dex_file,
91 cu->class_def_idx)) {
92 cg->GenMemBarrier(cu, kStoreStore);
93 }
buzbeefa57c472012-11-21 12:06:18 -080094 if (!(cu->attrs & METHOD_IS_LEAF)) {
buzbee02031b12012-11-23 09:41:35 -080095 cg->GenSuspendTest(cu, opt_flags);
Bill Buzbeea114add2012-05-03 15:00:40 -070096 }
97 break;
98
99 case Instruction::RETURN:
100 case Instruction::RETURN_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -0800101 if (!(cu->attrs & METHOD_IS_LEAF)) {
buzbee02031b12012-11-23 09:41:35 -0800102 cg->GenSuspendTest(cu, opt_flags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700103 }
buzbee02031b12012-11-23 09:41:35 -0800104 cg->StoreValue(cu, GetReturn(cu, cu->shorty[0] == 'F'), rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700105 break;
106
107 case Instruction::RETURN_WIDE:
buzbeefa57c472012-11-21 12:06:18 -0800108 if (!(cu->attrs & METHOD_IS_LEAF)) {
buzbee02031b12012-11-23 09:41:35 -0800109 cg->GenSuspendTest(cu, opt_flags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700110 }
buzbee02031b12012-11-23 09:41:35 -0800111 cg->StoreValueWide(cu, GetReturnWide(cu,
buzbeefa57c472012-11-21 12:06:18 -0800112 cu->shorty[0] == 'D'), rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700113 break;
114
115 case Instruction::MOVE_RESULT_WIDE:
buzbeefa57c472012-11-21 12:06:18 -0800116 if (opt_flags & MIR_INLINED)
buzbee02031b12012-11-23 09:41:35 -0800117 break; // Nop - combined w/ previous invoke.
118 cg->StoreValueWide(cu, rl_dest, GetReturnWide(cu, rl_dest.fp));
Bill Buzbeea114add2012-05-03 15:00:40 -0700119 break;
120
121 case Instruction::MOVE_RESULT:
122 case Instruction::MOVE_RESULT_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -0800123 if (opt_flags & MIR_INLINED)
buzbee02031b12012-11-23 09:41:35 -0800124 break; // Nop - combined w/ previous invoke.
125 cg->StoreValue(cu, rl_dest, GetReturn(cu, rl_dest.fp));
Bill Buzbeea114add2012-05-03 15:00:40 -0700126 break;
127
128 case Instruction::MOVE:
129 case Instruction::MOVE_OBJECT:
130 case Instruction::MOVE_16:
131 case Instruction::MOVE_OBJECT_16:
132 case Instruction::MOVE_FROM16:
133 case Instruction::MOVE_OBJECT_FROM16:
buzbee02031b12012-11-23 09:41:35 -0800134 cg->StoreValue(cu, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700135 break;
136
137 case Instruction::MOVE_WIDE:
138 case Instruction::MOVE_WIDE_16:
139 case Instruction::MOVE_WIDE_FROM16:
buzbee02031b12012-11-23 09:41:35 -0800140 cg->StoreValueWide(cu, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700141 break;
142
143 case Instruction::CONST:
144 case Instruction::CONST_4:
145 case Instruction::CONST_16:
buzbeefa57c472012-11-21 12:06:18 -0800146 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee02031b12012-11-23 09:41:35 -0800147 cg->LoadConstantNoClobber(cu, rl_result.low_reg, vB);
148 cg->StoreValue(cu, rl_dest, rl_result);
buzbee7da142f2012-11-29 16:33:42 -0800149 if (vB == 0) {
150 cg->Workaround7250540(cu, rl_dest, rl_result.low_reg);
151 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700152 break;
153
154 case Instruction::CONST_HIGH16:
buzbeefa57c472012-11-21 12:06:18 -0800155 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee02031b12012-11-23 09:41:35 -0800156 cg->LoadConstantNoClobber(cu, rl_result.low_reg, vB << 16);
157 cg->StoreValue(cu, rl_dest, rl_result);
buzbee7da142f2012-11-29 16:33:42 -0800158 if (vB == 0) {
159 cg->Workaround7250540(cu, rl_dest, rl_result.low_reg);
160 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700161 break;
162
163 case Instruction::CONST_WIDE_16:
164 case Instruction::CONST_WIDE_32:
buzbeefa57c472012-11-21 12:06:18 -0800165 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee02031b12012-11-23 09:41:35 -0800166 cg->LoadConstantValueWide(cu, rl_result.low_reg, rl_result.high_reg, vB,
buzbee408ad162012-06-06 16:45:18 -0700167 (vB & 0x80000000) ? -1 : 0);
buzbee02031b12012-11-23 09:41:35 -0800168 cg->StoreValueWide(cu, rl_dest, rl_result);
Bill Buzbeea114add2012-05-03 15:00:40 -0700169 break;
170
171 case Instruction::CONST_WIDE:
buzbeefa57c472012-11-21 12:06:18 -0800172 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee02031b12012-11-23 09:41:35 -0800173 cg->LoadConstantValueWide(cu, rl_result.low_reg, rl_result.high_reg,
Bill Buzbeea114add2012-05-03 15:00:40 -0700174 mir->dalvikInsn.vB_wide & 0xffffffff,
175 (mir->dalvikInsn.vB_wide >> 32) & 0xffffffff);
buzbee02031b12012-11-23 09:41:35 -0800176 cg->StoreValueWide(cu, rl_dest, rl_result);
Bill Buzbeea114add2012-05-03 15:00:40 -0700177 break;
178
179 case Instruction::CONST_WIDE_HIGH16:
buzbeefa57c472012-11-21 12:06:18 -0800180 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee02031b12012-11-23 09:41:35 -0800181 cg->LoadConstantValueWide(cu, rl_result.low_reg, rl_result.high_reg,
buzbee408ad162012-06-06 16:45:18 -0700182 0, vB << 16);
buzbee02031b12012-11-23 09:41:35 -0800183 cg->StoreValueWide(cu, rl_dest, rl_result);
Bill Buzbeea114add2012-05-03 15:00:40 -0700184 break;
185
186 case Instruction::MONITOR_ENTER:
buzbee02031b12012-11-23 09:41:35 -0800187 cg->GenMonitorEnter(cu, opt_flags, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700188 break;
189
190 case Instruction::MONITOR_EXIT:
buzbee02031b12012-11-23 09:41:35 -0800191 cg->GenMonitorExit(cu, opt_flags, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700192 break;
193
194 case Instruction::CHECK_CAST:
buzbee02031b12012-11-23 09:41:35 -0800195 cg->GenCheckCast(cu, vB, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700196 break;
197
198 case Instruction::INSTANCE_OF:
buzbee02031b12012-11-23 09:41:35 -0800199 cg->GenInstanceof(cu, vC, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700200 break;
201
202 case Instruction::NEW_INSTANCE:
buzbee02031b12012-11-23 09:41:35 -0800203 cg->GenNewInstance(cu, vB, rl_dest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700204 break;
205
206 case Instruction::THROW:
buzbee02031b12012-11-23 09:41:35 -0800207 cg->GenThrow(cu, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700208 break;
209
Bill Buzbeea114add2012-05-03 15:00:40 -0700210 case Instruction::ARRAY_LENGTH:
buzbeefa57c472012-11-21 12:06:18 -0800211 int len_offset;
212 len_offset = Array::LengthOffset().Int32Value();
buzbee02031b12012-11-23 09:41:35 -0800213 rl_src[0] = cg->LoadValue(cu, rl_src[0], kCoreReg);
214 cg->GenNullCheck(cu, rl_src[0].s_reg_low, rl_src[0].low_reg, opt_flags);
buzbeefa57c472012-11-21 12:06:18 -0800215 rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
buzbee02031b12012-11-23 09:41:35 -0800216 cg->LoadWordDisp(cu, rl_src[0].low_reg, len_offset, rl_result.low_reg);
217 cg->StoreValue(cu, rl_dest, rl_result);
Bill Buzbeea114add2012-05-03 15:00:40 -0700218 break;
219
220 case Instruction::CONST_STRING:
221 case Instruction::CONST_STRING_JUMBO:
buzbee02031b12012-11-23 09:41:35 -0800222 cg->GenConstString(cu, vB, rl_dest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700223 break;
224
225 case Instruction::CONST_CLASS:
buzbee02031b12012-11-23 09:41:35 -0800226 cg->GenConstClass(cu, vB, rl_dest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700227 break;
228
229 case Instruction::FILL_ARRAY_DATA:
buzbee02031b12012-11-23 09:41:35 -0800230 cg->GenFillArrayData(cu, vB, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700231 break;
232
233 case Instruction::FILLED_NEW_ARRAY:
buzbee02031b12012-11-23 09:41:35 -0800234 cg->GenFilledNewArray(cu, cg->NewMemCallInfo(cu, bb, mir, kStatic,
buzbee3b3dbdd2012-06-13 13:39:34 -0700235 false /* not range */));
Bill Buzbeea114add2012-05-03 15:00:40 -0700236 break;
237
238 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800239 cg->GenFilledNewArray(cu, cg->NewMemCallInfo(cu, bb, mir, kStatic,
buzbee3b3dbdd2012-06-13 13:39:34 -0700240 true /* range */));
Bill Buzbeea114add2012-05-03 15:00:40 -0700241 break;
242
243 case Instruction::NEW_ARRAY:
buzbee02031b12012-11-23 09:41:35 -0800244 cg->GenNewArray(cu, vC, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700245 break;
246
247 case Instruction::GOTO:
248 case Instruction::GOTO_16:
249 case Instruction::GOTO_32:
buzbeefa57c472012-11-21 12:06:18 -0800250 if (bb->taken->start_offset <= mir->offset) {
buzbee02031b12012-11-23 09:41:35 -0800251 cg->GenSuspendTestAndBranch(cu, opt_flags, &label_list[bb->taken->id]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700252 } else {
buzbee02031b12012-11-23 09:41:35 -0800253 cg->OpUnconditionalBranch(cu, &label_list[bb->taken->id]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700254 }
255 break;
256
257 case Instruction::PACKED_SWITCH:
buzbee02031b12012-11-23 09:41:35 -0800258 cg->GenPackedSwitch(cu, vB, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700259 break;
260
261 case Instruction::SPARSE_SWITCH:
buzbee02031b12012-11-23 09:41:35 -0800262 cg->GenSparseSwitch(cu, vB, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700263 break;
264
265 case Instruction::CMPL_FLOAT:
266 case Instruction::CMPG_FLOAT:
267 case Instruction::CMPL_DOUBLE:
268 case Instruction::CMPG_DOUBLE:
buzbee02031b12012-11-23 09:41:35 -0800269 res = cg->GenCmpFP(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700270 break;
271
272 case Instruction::CMP_LONG:
buzbee02031b12012-11-23 09:41:35 -0800273 cg->GenCmpLong(cu, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700274 break;
275
276 case Instruction::IF_EQ:
277 case Instruction::IF_NE:
278 case Instruction::IF_LT:
279 case Instruction::IF_GE:
280 case Instruction::IF_GT:
281 case Instruction::IF_LE: {
buzbeefa57c472012-11-21 12:06:18 -0800282 LIR* taken = &label_list[bb->taken->id];
283 LIR* fall_through = &label_list[bb->fall_through->id];
284 bool backward_branch;
285 backward_branch = (bb->taken->start_offset <= mir->offset);
buzbeee6285f92012-12-06 15:57:46 -0800286 // Result known at compile time?
287 if (rl_src[0].is_const && rl_src[1].is_const) {
288 bool is_taken = EvaluateBranch(opcode, cu->constant_values[rl_src[0].orig_sreg],
289 cu->constant_values[rl_src[1].orig_sreg]);
290 if (is_taken && backward_branch) {
291 cg->GenSuspendTest(cu, opt_flags);
292 }
293 int id = is_taken ? bb->taken->id : bb->fall_through->id;
294 cg->OpUnconditionalBranch(cu, &label_list[id]);
295 } else {
296 if (backward_branch) {
297 cg->GenSuspendTest(cu, opt_flags);
298 }
299 cg->GenCompareAndBranch(cu, opcode, rl_src[0], rl_src[1], taken,
300 fall_through);
Bill Buzbeea114add2012-05-03 15:00:40 -0700301 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700302 break;
303 }
304
305 case Instruction::IF_EQZ:
306 case Instruction::IF_NEZ:
307 case Instruction::IF_LTZ:
308 case Instruction::IF_GEZ:
309 case Instruction::IF_GTZ:
310 case Instruction::IF_LEZ: {
buzbeefa57c472012-11-21 12:06:18 -0800311 LIR* taken = &label_list[bb->taken->id];
312 LIR* fall_through = &label_list[bb->fall_through->id];
313 bool backward_branch;
314 backward_branch = (bb->taken->start_offset <= mir->offset);
buzbeee6285f92012-12-06 15:57:46 -0800315 // Result known at compile time?
316 if (rl_src[0].is_const) {
317 bool is_taken = EvaluateBranch(opcode, cu->constant_values[rl_src[0].orig_sreg], 0);
318 if (is_taken && backward_branch) {
319 cg->GenSuspendTest(cu, opt_flags);
320 }
321 int id = is_taken ? bb->taken->id : bb->fall_through->id;
322 cg->OpUnconditionalBranch(cu, &label_list[id]);
323 } else {
324 if (backward_branch) {
325 cg->GenSuspendTest(cu, opt_flags);
326 }
327 cg->GenCompareZeroAndBranch(cu, opcode, rl_src[0], taken, fall_through);
Bill Buzbeea114add2012-05-03 15:00:40 -0700328 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700329 break;
330 }
331
332 case Instruction::AGET_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800333 cg->GenArrayGet(cu, opt_flags, kLong, rl_src[0], rl_src[1], rl_dest, 3);
Bill Buzbeea114add2012-05-03 15:00:40 -0700334 break;
335 case Instruction::AGET:
336 case Instruction::AGET_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800337 cg->GenArrayGet(cu, opt_flags, kWord, rl_src[0], rl_src[1], rl_dest, 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700338 break;
339 case Instruction::AGET_BOOLEAN:
buzbee02031b12012-11-23 09:41:35 -0800340 cg->GenArrayGet(cu, opt_flags, kUnsignedByte, rl_src[0], rl_src[1], rl_dest, 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700341 break;
342 case Instruction::AGET_BYTE:
buzbee02031b12012-11-23 09:41:35 -0800343 cg->GenArrayGet(cu, opt_flags, kSignedByte, rl_src[0], rl_src[1], rl_dest, 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700344 break;
345 case Instruction::AGET_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800346 cg->GenArrayGet(cu, opt_flags, kUnsignedHalf, rl_src[0], rl_src[1], rl_dest, 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700347 break;
348 case Instruction::AGET_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800349 cg->GenArrayGet(cu, opt_flags, kSignedHalf, rl_src[0], rl_src[1], rl_dest, 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700350 break;
351 case Instruction::APUT_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800352 cg->GenArrayPut(cu, opt_flags, kLong, rl_src[1], rl_src[2], rl_src[0], 3);
Bill Buzbeea114add2012-05-03 15:00:40 -0700353 break;
354 case Instruction::APUT:
buzbee02031b12012-11-23 09:41:35 -0800355 cg->GenArrayPut(cu, opt_flags, kWord, rl_src[1], rl_src[2], rl_src[0], 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700356 break;
357 case Instruction::APUT_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800358 cg->GenArrayObjPut(cu, opt_flags, rl_src[1], rl_src[2], rl_src[0], 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700359 break;
360 case Instruction::APUT_SHORT:
361 case Instruction::APUT_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800362 cg->GenArrayPut(cu, opt_flags, kUnsignedHalf, rl_src[1], rl_src[2], rl_src[0], 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700363 break;
364 case Instruction::APUT_BYTE:
365 case Instruction::APUT_BOOLEAN:
buzbee02031b12012-11-23 09:41:35 -0800366 cg->GenArrayPut(cu, opt_flags, kUnsignedByte, rl_src[1], rl_src[2],
buzbeefa57c472012-11-21 12:06:18 -0800367 rl_src[0], 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700368 break;
369
370 case Instruction::IGET_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800371 cg->GenIGet(cu, vC, opt_flags, kWord, rl_dest, rl_src[0], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700372 break;
373
374 case Instruction::IGET_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800375 cg->GenIGet(cu, vC, opt_flags, kLong, rl_dest, rl_src[0], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700376 break;
377
378 case Instruction::IGET:
buzbee02031b12012-11-23 09:41:35 -0800379 cg->GenIGet(cu, vC, opt_flags, kWord, rl_dest, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700380 break;
381
382 case Instruction::IGET_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800383 cg->GenIGet(cu, vC, opt_flags, kUnsignedHalf, rl_dest, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700384 break;
385
386 case Instruction::IGET_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800387 cg->GenIGet(cu, vC, opt_flags, kSignedHalf, rl_dest, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700388 break;
389
390 case Instruction::IGET_BOOLEAN:
391 case Instruction::IGET_BYTE:
buzbee02031b12012-11-23 09:41:35 -0800392 cg->GenIGet(cu, vC, opt_flags, kUnsignedByte, rl_dest, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700393 break;
394
395 case Instruction::IPUT_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800396 cg->GenIPut(cu, vC, opt_flags, kLong, rl_src[0], rl_src[1], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700397 break;
398
399 case Instruction::IPUT_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800400 cg->GenIPut(cu, vC, opt_flags, kWord, rl_src[0], rl_src[1], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700401 break;
402
403 case Instruction::IPUT:
buzbee02031b12012-11-23 09:41:35 -0800404 cg->GenIPut(cu, vC, opt_flags, kWord, rl_src[0], rl_src[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700405 break;
406
407 case Instruction::IPUT_BOOLEAN:
408 case Instruction::IPUT_BYTE:
buzbee02031b12012-11-23 09:41:35 -0800409 cg->GenIPut(cu, vC, opt_flags, kUnsignedByte, rl_src[0], rl_src[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700410 break;
411
412 case Instruction::IPUT_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800413 cg->GenIPut(cu, vC, opt_flags, kUnsignedHalf, rl_src[0], rl_src[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700414 break;
415
416 case Instruction::IPUT_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800417 cg->GenIPut(cu, vC, opt_flags, kSignedHalf, rl_src[0], rl_src[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700418 break;
419
420 case Instruction::SGET_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800421 cg->GenSget(cu, vB, rl_dest, false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700422 break;
423 case Instruction::SGET:
424 case Instruction::SGET_BOOLEAN:
425 case Instruction::SGET_BYTE:
426 case Instruction::SGET_CHAR:
427 case Instruction::SGET_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800428 cg->GenSget(cu, vB, rl_dest, false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700429 break;
430
431 case Instruction::SGET_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800432 cg->GenSget(cu, vB, rl_dest, true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700433 break;
434
435 case Instruction::SPUT_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800436 cg->GenSput(cu, vB, rl_src[0], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700437 break;
438
439 case Instruction::SPUT:
440 case Instruction::SPUT_BOOLEAN:
441 case Instruction::SPUT_BYTE:
442 case Instruction::SPUT_CHAR:
443 case Instruction::SPUT_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800444 cg->GenSput(cu, vB, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700445 break;
446
447 case Instruction::SPUT_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800448 cg->GenSput(cu, vB, rl_src[0], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700449 break;
450
451 case Instruction::INVOKE_STATIC_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800452 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kStatic, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700453 break;
454 case Instruction::INVOKE_STATIC:
buzbee02031b12012-11-23 09:41:35 -0800455 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kStatic, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700456 break;
457
458 case Instruction::INVOKE_DIRECT:
buzbee02031b12012-11-23 09:41:35 -0800459 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kDirect, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700460 break;
461 case Instruction::INVOKE_DIRECT_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800462 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kDirect, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700463 break;
464
465 case Instruction::INVOKE_VIRTUAL:
buzbee02031b12012-11-23 09:41:35 -0800466 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kVirtual, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700467 break;
468 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800469 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kVirtual, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700470 break;
471
472 case Instruction::INVOKE_SUPER:
buzbee02031b12012-11-23 09:41:35 -0800473 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kSuper, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700474 break;
475 case Instruction::INVOKE_SUPER_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800476 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kSuper, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700477 break;
478
479 case Instruction::INVOKE_INTERFACE:
buzbee02031b12012-11-23 09:41:35 -0800480 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kInterface, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700481 break;
482 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800483 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kInterface, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700484 break;
485
486 case Instruction::NEG_INT:
487 case Instruction::NOT_INT:
buzbee02031b12012-11-23 09:41:35 -0800488 res = cg->GenArithOpInt(cu, opcode, rl_dest, rl_src[0], rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700489 break;
490
491 case Instruction::NEG_LONG:
492 case Instruction::NOT_LONG:
buzbee02031b12012-11-23 09:41:35 -0800493 res = cg->GenArithOpLong(cu, opcode, rl_dest, rl_src[0], rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700494 break;
495
496 case Instruction::NEG_FLOAT:
buzbee02031b12012-11-23 09:41:35 -0800497 res = cg->GenArithOpFloat(cu, opcode, rl_dest, rl_src[0], rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700498 break;
499
500 case Instruction::NEG_DOUBLE:
buzbee02031b12012-11-23 09:41:35 -0800501 res = cg->GenArithOpDouble(cu, opcode, rl_dest, rl_src[0], rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700502 break;
503
504 case Instruction::INT_TO_LONG:
buzbee02031b12012-11-23 09:41:35 -0800505 cg->GenIntToLong(cu, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700506 break;
507
508 case Instruction::LONG_TO_INT:
buzbeefa57c472012-11-21 12:06:18 -0800509 rl_src[0] = UpdateLocWide(cu, rl_src[0]);
510 rl_src[0] = WideToNarrow(cu, rl_src[0]);
buzbee02031b12012-11-23 09:41:35 -0800511 cg->StoreValue(cu, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700512 break;
513
514 case Instruction::INT_TO_BYTE:
515 case Instruction::INT_TO_SHORT:
516 case Instruction::INT_TO_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800517 cg->GenIntNarrowing(cu, opcode, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700518 break;
519
520 case Instruction::INT_TO_FLOAT:
521 case Instruction::INT_TO_DOUBLE:
522 case Instruction::LONG_TO_FLOAT:
523 case Instruction::LONG_TO_DOUBLE:
524 case Instruction::FLOAT_TO_INT:
525 case Instruction::FLOAT_TO_LONG:
526 case Instruction::FLOAT_TO_DOUBLE:
527 case Instruction::DOUBLE_TO_INT:
528 case Instruction::DOUBLE_TO_LONG:
529 case Instruction::DOUBLE_TO_FLOAT:
buzbee02031b12012-11-23 09:41:35 -0800530 cg->GenConversion(cu, opcode, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700531 break;
532
buzbeee6285f92012-12-06 15:57:46 -0800533
Bill Buzbeea114add2012-05-03 15:00:40 -0700534 case Instruction::ADD_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700535 case Instruction::ADD_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800536 case Instruction::MUL_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700537 case Instruction::MUL_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800538 case Instruction::AND_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700539 case Instruction::AND_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800540 case Instruction::OR_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700541 case Instruction::OR_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800542 case Instruction::XOR_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700543 case Instruction::XOR_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800544 if (rl_src[0].is_const &&
545 cu->cg->InexpensiveConstant(0, cu->constant_values[rl_src[0].orig_sreg])) {
546 cg->GenArithOpIntLit(cu, opcode, rl_dest, rl_src[1],
547 cu->constant_values[rl_src[0].orig_sreg]);
548 } else if (rl_src[1].is_const &&
549 cu->cg->InexpensiveConstant(0, cu->constant_values[rl_src[1].orig_sreg])) {
550 cg->GenArithOpIntLit(cu, opcode, rl_dest, rl_src[0],
551 cu->constant_values[rl_src[1].orig_sreg]);
552 } else {
553 cg->GenArithOpInt(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
554 }
555 break;
556
557 case Instruction::SUB_INT:
558 case Instruction::SUB_INT_2ADDR:
559 case Instruction::DIV_INT:
560 case Instruction::DIV_INT_2ADDR:
561 case Instruction::REM_INT:
562 case Instruction::REM_INT_2ADDR:
563 case Instruction::SHL_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700564 case Instruction::SHL_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800565 case Instruction::SHR_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700566 case Instruction::SHR_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800567 case Instruction::USHR_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700568 case Instruction::USHR_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800569 if (rl_src[1].is_const &&
570 cu->cg->InexpensiveConstant(0, cu->constant_values[rl_src[1].orig_sreg])) {
571 cg->GenArithOpIntLit(cu, opcode, rl_dest, rl_src[0],
572 cu->constant_values[rl_src[1].orig_sreg]);
573 } else {
574 cg->GenArithOpInt(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
575 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700576 break;
577
578 case Instruction::ADD_LONG:
579 case Instruction::SUB_LONG:
580 case Instruction::MUL_LONG:
581 case Instruction::DIV_LONG:
582 case Instruction::REM_LONG:
583 case Instruction::AND_LONG:
584 case Instruction::OR_LONG:
585 case Instruction::XOR_LONG:
586 case Instruction::ADD_LONG_2ADDR:
587 case Instruction::SUB_LONG_2ADDR:
588 case Instruction::MUL_LONG_2ADDR:
589 case Instruction::DIV_LONG_2ADDR:
590 case Instruction::REM_LONG_2ADDR:
591 case Instruction::AND_LONG_2ADDR:
592 case Instruction::OR_LONG_2ADDR:
593 case Instruction::XOR_LONG_2ADDR:
buzbee02031b12012-11-23 09:41:35 -0800594 cg->GenArithOpLong(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700595 break;
596
597 case Instruction::SHL_LONG:
598 case Instruction::SHR_LONG:
599 case Instruction::USHR_LONG:
600 case Instruction::SHL_LONG_2ADDR:
601 case Instruction::SHR_LONG_2ADDR:
602 case Instruction::USHR_LONG_2ADDR:
buzbee02031b12012-11-23 09:41:35 -0800603 cg->GenShiftOpLong(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700604 break;
605
606 case Instruction::ADD_FLOAT:
607 case Instruction::SUB_FLOAT:
608 case Instruction::MUL_FLOAT:
609 case Instruction::DIV_FLOAT:
610 case Instruction::REM_FLOAT:
611 case Instruction::ADD_FLOAT_2ADDR:
612 case Instruction::SUB_FLOAT_2ADDR:
613 case Instruction::MUL_FLOAT_2ADDR:
614 case Instruction::DIV_FLOAT_2ADDR:
615 case Instruction::REM_FLOAT_2ADDR:
buzbee02031b12012-11-23 09:41:35 -0800616 cg->GenArithOpFloat(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700617 break;
618
619 case Instruction::ADD_DOUBLE:
620 case Instruction::SUB_DOUBLE:
621 case Instruction::MUL_DOUBLE:
622 case Instruction::DIV_DOUBLE:
623 case Instruction::REM_DOUBLE:
624 case Instruction::ADD_DOUBLE_2ADDR:
625 case Instruction::SUB_DOUBLE_2ADDR:
626 case Instruction::MUL_DOUBLE_2ADDR:
627 case Instruction::DIV_DOUBLE_2ADDR:
628 case Instruction::REM_DOUBLE_2ADDR:
buzbee02031b12012-11-23 09:41:35 -0800629 cg->GenArithOpDouble(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700630 break;
631
632 case Instruction::RSUB_INT:
633 case Instruction::ADD_INT_LIT16:
634 case Instruction::MUL_INT_LIT16:
635 case Instruction::DIV_INT_LIT16:
636 case Instruction::REM_INT_LIT16:
637 case Instruction::AND_INT_LIT16:
638 case Instruction::OR_INT_LIT16:
639 case Instruction::XOR_INT_LIT16:
640 case Instruction::ADD_INT_LIT8:
641 case Instruction::RSUB_INT_LIT8:
642 case Instruction::MUL_INT_LIT8:
643 case Instruction::DIV_INT_LIT8:
644 case Instruction::REM_INT_LIT8:
645 case Instruction::AND_INT_LIT8:
646 case Instruction::OR_INT_LIT8:
647 case Instruction::XOR_INT_LIT8:
648 case Instruction::SHL_INT_LIT8:
649 case Instruction::SHR_INT_LIT8:
650 case Instruction::USHR_INT_LIT8:
buzbee02031b12012-11-23 09:41:35 -0800651 cg->GenArithOpIntLit(cu, opcode, rl_dest, rl_src[0], vC);
Bill Buzbeea114add2012-05-03 15:00:40 -0700652 break;
653
654 default:
655 res = true;
656 }
657 return res;
buzbeee3acd072012-02-25 17:03:10 -0800658}
659
buzbeea169e1d2012-12-05 14:26:44 -0800660// Process extended MIR instructions
buzbeefa57c472012-11-21 12:06:18 -0800661static void HandleExtendedMethodMIR(CompilationUnit* cu, BasicBlock* bb, MIR* mir)
buzbeee3acd072012-02-25 17:03:10 -0800662{
buzbee02031b12012-11-23 09:41:35 -0800663 Codegen* cg = cu->cg.get();
buzbeecbd6d442012-11-17 14:11:25 -0800664 switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700665 case kMirOpCopy: {
buzbeefa57c472012-11-21 12:06:18 -0800666 RegLocation rl_src = GetSrc(cu, mir, 0);
667 RegLocation rl_dest = GetDest(cu, mir);
buzbee02031b12012-11-23 09:41:35 -0800668 cg->StoreValue(cu, rl_dest, rl_src);
Bill Buzbeea114add2012-05-03 15:00:40 -0700669 break;
670 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700671 case kMirOpFusedCmplFloat:
buzbee02031b12012-11-23 09:41:35 -0800672 cg->GenFusedFPCmpBranch(cu, bb, mir, false /*gt bias*/, false /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700673 break;
674 case kMirOpFusedCmpgFloat:
buzbee02031b12012-11-23 09:41:35 -0800675 cg->GenFusedFPCmpBranch(cu, bb, mir, true /*gt bias*/, false /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700676 break;
677 case kMirOpFusedCmplDouble:
buzbee02031b12012-11-23 09:41:35 -0800678 cg->GenFusedFPCmpBranch(cu, bb, mir, false /*gt bias*/, true /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700679 break;
680 case kMirOpFusedCmpgDouble:
buzbee02031b12012-11-23 09:41:35 -0800681 cg->GenFusedFPCmpBranch(cu, bb, mir, true /*gt bias*/, true /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700682 break;
683 case kMirOpFusedCmpLong:
buzbee02031b12012-11-23 09:41:35 -0800684 cg->GenFusedLongCmpBranch(cu, bb, mir);
Bill Buzbeea114add2012-05-03 15:00:40 -0700685 break;
Bill Buzbeea114add2012-05-03 15:00:40 -0700686 default:
687 break;
688 }
buzbeee3acd072012-02-25 17:03:10 -0800689}
690
buzbee02031b12012-11-23 09:41:35 -0800691// Handle the content in each basic block.
buzbeefa57c472012-11-21 12:06:18 -0800692static bool MethodBlockCodeGen(CompilationUnit* cu, BasicBlock* bb)
buzbeee3acd072012-02-25 17:03:10 -0800693{
buzbeefa57c472012-11-21 12:06:18 -0800694 if (bb->block_type == kDead) return false;
buzbee02031b12012-11-23 09:41:35 -0800695 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -0800696 cu->current_dalvik_offset = bb->start_offset;
Bill Buzbeea114add2012-05-03 15:00:40 -0700697 MIR* mir;
buzbeefa57c472012-11-21 12:06:18 -0800698 LIR* label_list = cu->block_label_list;
699 int block_id = bb->id;
buzbeee3acd072012-02-25 17:03:10 -0800700
buzbeefa57c472012-11-21 12:06:18 -0800701 cu->cur_block = bb;
702 label_list[block_id].operands[0] = bb->start_offset;
buzbeee3acd072012-02-25 17:03:10 -0800703
buzbee02031b12012-11-23 09:41:35 -0800704 // Insert the block label.
buzbeefa57c472012-11-21 12:06:18 -0800705 label_list[block_id].opcode = kPseudoNormalBlockLabel;
706 AppendLIR(cu, &label_list[block_id]);
buzbeee3acd072012-02-25 17:03:10 -0800707
buzbeefa57c472012-11-21 12:06:18 -0800708 LIR* head_lir = NULL;
buzbee8320f382012-09-11 16:29:42 -0700709
buzbee02031b12012-11-23 09:41:35 -0800710 // If this is a catch block, export the start address.
buzbeefa57c472012-11-21 12:06:18 -0800711 if (bb->catch_entry) {
712 head_lir = NewLIR0(cu, kPseudoExportedPC);
buzbee8320f382012-09-11 16:29:42 -0700713 }
714
buzbee02031b12012-11-23 09:41:35 -0800715 // Free temp registers and reset redundant store tracking.
buzbeefa57c472012-11-21 12:06:18 -0800716 ResetRegPool(cu);
717 ResetDefTracking(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700718
buzbeefa57c472012-11-21 12:06:18 -0800719 ClobberAllRegs(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700720
buzbeefa57c472012-11-21 12:06:18 -0800721 if (bb->block_type == kEntryBlock) {
722 int start_vreg = cu->num_dalvik_registers - cu->num_ins;
buzbee02031b12012-11-23 09:41:35 -0800723 cg->GenEntrySequence(cu, &cu->reg_location[start_vreg],
724 cu->reg_location[cu->method_sreg]);
buzbeefa57c472012-11-21 12:06:18 -0800725 } else if (bb->block_type == kExitBlock) {
buzbee02031b12012-11-23 09:41:35 -0800726 cg->GenExitSequence(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700727 }
728
buzbee28c9a832012-11-21 15:39:13 -0800729 for (mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
buzbeefa57c472012-11-21 12:06:18 -0800730 ResetRegPool(cu);
731 if (cu->disable_opt & (1 << kTrackLiveTemps)) {
732 ClobberAllRegs(cu);
buzbeee1965672012-03-11 18:39:19 -0700733 }
734
buzbeefa57c472012-11-21 12:06:18 -0800735 if (cu->disable_opt & (1 << kSuppressLoads)) {
736 ResetDefTracking(cu);
buzbeee3acd072012-02-25 17:03:10 -0800737 }
738
buzbee3d661942012-03-14 17:37:27 -0700739#ifndef NDEBUG
buzbee02031b12012-11-23 09:41:35 -0800740 // Reset temp tracking sanity check.
buzbeefa57c472012-11-21 12:06:18 -0800741 cu->live_sreg = INVALID_SREG;
buzbee3d661942012-03-14 17:37:27 -0700742#endif
743
buzbeefa57c472012-11-21 12:06:18 -0800744 cu->current_dalvik_offset = mir->offset;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700745 int opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -0800746 LIR* boundary_lir;
buzbeee3acd072012-02-25 17:03:10 -0800747
buzbee02031b12012-11-23 09:41:35 -0800748 // Mark the beginning of a Dalvik instruction for line tracking.
buzbeefa57c472012-11-21 12:06:18 -0800749 char* inst_str = cu->verbose ?
buzbeea169e1d2012-12-05 14:26:44 -0800750 GetDalvikDisassembly(cu, mir) : NULL;
buzbeefa57c472012-11-21 12:06:18 -0800751 boundary_lir = MarkBoundary(cu, mir->offset, inst_str);
buzbee02031b12012-11-23 09:41:35 -0800752 // Remember the first LIR for this block.
buzbeefa57c472012-11-21 12:06:18 -0800753 if (head_lir == NULL) {
754 head_lir = boundary_lir;
buzbee02031b12012-11-23 09:41:35 -0800755 // Set the first boundary_lir as a scheduling barrier.
buzbeefa57c472012-11-21 12:06:18 -0800756 head_lir->def_mask = ENCODE_ALL;
buzbeee3acd072012-02-25 17:03:10 -0800757 }
758
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700759 if (opcode == kMirOpCheck) {
760 // Combine check and work halves of throwing instruction.
buzbeefa57c472012-11-21 12:06:18 -0800761 MIR* work_half = mir->meta.throw_insn;
762 mir->dalvikInsn.opcode = work_half->dalvikInsn.opcode;
763 opcode = work_half->dalvikInsn.opcode;
764 SSARepresentation* ssa_rep = work_half->ssa_rep;
765 work_half->ssa_rep = mir->ssa_rep;
766 mir->ssa_rep = ssa_rep;
buzbeea169e1d2012-12-05 14:26:44 -0800767 work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpCheckPart2);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700768 }
769
770 if (opcode >= kMirOpFirst) {
buzbeefa57c472012-11-21 12:06:18 -0800771 HandleExtendedMethodMIR(cu, bb, mir);
Bill Buzbeea114add2012-05-03 15:00:40 -0700772 continue;
773 }
774
buzbeefa57c472012-11-21 12:06:18 -0800775 bool not_handled = CompileDalvikInstruction(cu, mir, bb, label_list);
776 if (not_handled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700777 LOG(FATAL) << StringPrintf("%#06x: Opcode %#x (%s)",
778 mir->offset, opcode,
779 Instruction::Name(mir->dalvikInsn.opcode));
Bill Buzbeea114add2012-05-03 15:00:40 -0700780 }
781 }
782
buzbeefa57c472012-11-21 12:06:18 -0800783 if (head_lir) {
buzbee02031b12012-11-23 09:41:35 -0800784 // Eliminate redundant loads/stores and delay stores into later slots.
buzbeefa57c472012-11-21 12:06:18 -0800785 ApplyLocalOptimizations(cu, head_lir, cu->last_lir_insn);
Bill Buzbeea114add2012-05-03 15:00:40 -0700786
buzbee02031b12012-11-23 09:41:35 -0800787 // Generate an unconditional branch to the fallthrough block.
buzbeefa57c472012-11-21 12:06:18 -0800788 if (bb->fall_through) {
buzbee02031b12012-11-23 09:41:35 -0800789 cg->OpUnconditionalBranch(cu, &label_list[bb->fall_through->id]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700790 }
791 }
792 return false;
buzbeee3acd072012-02-25 17:03:10 -0800793}
794
buzbeefa57c472012-11-21 12:06:18 -0800795void SpecialMIR2LIR(CompilationUnit* cu, SpecialCaseHandler special_case)
buzbee16da88c2012-03-20 10:38:17 -0700796{
buzbee02031b12012-11-23 09:41:35 -0800797 Codegen* cg = cu->cg.get();
798 // Find the first DalvikByteCode block.
buzbeefa57c472012-11-21 12:06:18 -0800799 int num_reachable_blocks = cu->num_reachable_blocks;
800 const GrowableList *block_list = &cu->block_list;
Bill Buzbeea114add2012-05-03 15:00:40 -0700801 BasicBlock*bb = NULL;
buzbeefa57c472012-11-21 12:06:18 -0800802 for (int idx = 0; idx < num_reachable_blocks; idx++) {
803 int dfs_index = cu->dfs_order.elem_list[idx];
804 bb = reinterpret_cast<BasicBlock*>(GrowableListGetElement(block_list, dfs_index));
805 if (bb->block_type == kDalvikByteCode) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700806 break;
buzbee16da88c2012-03-20 10:38:17 -0700807 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700808 }
809 if (bb == NULL) {
810 return;
811 }
buzbeefa57c472012-11-21 12:06:18 -0800812 DCHECK_EQ(bb->start_offset, 0);
813 DCHECK(bb->first_mir_insn != NULL);
buzbee16da88c2012-03-20 10:38:17 -0700814
buzbee02031b12012-11-23 09:41:35 -0800815 // Get the first instruction.
buzbeefa57c472012-11-21 12:06:18 -0800816 MIR* mir = bb->first_mir_insn;
buzbee16da88c2012-03-20 10:38:17 -0700817
buzbee02031b12012-11-23 09:41:35 -0800818 // Free temp registers and reset redundant store tracking.
buzbeefa57c472012-11-21 12:06:18 -0800819 ResetRegPool(cu);
820 ResetDefTracking(cu);
821 ClobberAllRegs(cu);
buzbee16da88c2012-03-20 10:38:17 -0700822
buzbee02031b12012-11-23 09:41:35 -0800823 cg->GenSpecialCase(cu, bb, mir, special_case);
buzbee16da88c2012-03-20 10:38:17 -0700824}
825
buzbeefa57c472012-11-21 12:06:18 -0800826void MethodMIR2LIR(CompilationUnit* cu)
buzbeee3acd072012-02-25 17:03:10 -0800827{
buzbee02031b12012-11-23 09:41:35 -0800828 Codegen* cg = cu->cg.get();
829 // Hold the labels of each block.
buzbeefa57c472012-11-21 12:06:18 -0800830 cu->block_label_list =
831 static_cast<LIR*>(NewMem(cu, sizeof(LIR) * cu->num_blocks, true, kAllocLIR));
buzbeee3acd072012-02-25 17:03:10 -0800832
buzbeefa57c472012-11-21 12:06:18 -0800833 DataFlowAnalysisDispatcher(cu, MethodBlockCodeGen,
Bill Buzbeea114add2012-05-03 15:00:40 -0700834 kPreOrderDFSTraversal, false /* Iterative */);
Ian Rogersab2b55d2012-03-18 00:06:11 -0700835
buzbee02031b12012-11-23 09:41:35 -0800836 cg->HandleSuspendLaunchPads(cu);
buzbeee3acd072012-02-25 17:03:10 -0800837
buzbee02031b12012-11-23 09:41:35 -0800838 cg->HandleThrowLaunchPads(cu);
buzbeee3acd072012-02-25 17:03:10 -0800839
buzbee02031b12012-11-23 09:41:35 -0800840 cg->HandleIntrinsicLaunchPads(cu);
buzbeefc9e6fa2012-03-23 15:14:29 -0700841
buzbeefa57c472012-11-21 12:06:18 -0800842 if (!(cu->disable_opt & (1 << kSafeOptimizations))) {
843 RemoveRedundantBranches(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700844 }
buzbeee3acd072012-02-25 17:03:10 -0800845}
846
buzbeee3acd072012-02-25 17:03:10 -0800847} // namespace art