blob: 733552c9a989e3244a7c28417716aa842298970d [file] [log] [blame]
buzbee67bf8852011-08-17 17:51:35 -07001/*
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 "Dalvik.h"
18#include "Dataflow.h"
19//#include "libdex/DexOpcodes.h"
20
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080021namespace art {
22
buzbee67bf8852011-08-17 17:51:35 -070023/*
24 * Main table containing data flow attributes for each bytecode. The
25 * first kNumPackedOpcodes entries are for Dalvik bytecode
26 * instructions, where extended opcode at the MIR level are appended
27 * afterwards.
28 *
29 * TODO - many optimization flags are incomplete - they will only limit the
30 * scope of optimizations but will not cause mis-optimizations.
31 */
buzbeeba938cb2012-02-03 14:47:55 -080032const int oatDataFlowAttributes[kMirOpLast] = {
buzbee67bf8852011-08-17 17:51:35 -070033 // 00 OP_NOP
34 DF_NOP,
35
36 // 01 OP_MOVE vA, vB
37 DF_DA | DF_UB | DF_IS_MOVE,
38
39 // 02 OP_MOVE_FROM16 vAA, vBBBB
40 DF_DA | DF_UB | DF_IS_MOVE,
41
42 // 03 OP_MOVE_16 vAAAA, vBBBB
43 DF_DA | DF_UB | DF_IS_MOVE,
44
45 // 04 OP_MOVE_WIDE vA, vB
46 DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
47
48 // 05 OP_MOVE_WIDE_FROM16 vAA, vBBBB
49 DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
50
51 // 06 OP_MOVE_WIDE_16 vAAAA, vBBBB
52 DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
53
54 // 07 OP_MOVE_OBJECT vA, vB
buzbee67bc2362011-10-11 18:08:40 -070055 DF_DA | DF_UB | DF_NULL_TRANSFER_0 | DF_IS_MOVE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -070056
57 // 08 OP_MOVE_OBJECT_FROM16 vAA, vBBBB
buzbee67bc2362011-10-11 18:08:40 -070058 DF_DA | DF_UB | DF_NULL_TRANSFER_0 | DF_IS_MOVE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -070059
60 // 09 OP_MOVE_OBJECT_16 vAAAA, vBBBB
buzbee67bc2362011-10-11 18:08:40 -070061 DF_DA | DF_UB | DF_NULL_TRANSFER_0 | DF_IS_MOVE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -070062
63 // 0A OP_MOVE_RESULT vAA
64 DF_DA,
65
66 // 0B OP_MOVE_RESULT_WIDE vAA
67 DF_DA_WIDE,
68
69 // 0C OP_MOVE_RESULT_OBJECT vAA
buzbee67bc2362011-10-11 18:08:40 -070070 DF_DA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -070071
72 // 0D OP_MOVE_EXCEPTION vAA
buzbee67bc2362011-10-11 18:08:40 -070073 DF_DA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -070074
75 // 0E OP_RETURN_VOID
76 DF_NOP,
77
78 // 0F OP_RETURN vAA
79 DF_UA,
80
81 // 10 OP_RETURN_WIDE vAA
82 DF_UA_WIDE,
83
84 // 11 OP_RETURN_OBJECT vAA
buzbee67bc2362011-10-11 18:08:40 -070085 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -070086
87 // 12 OP_CONST_4 vA, #+B
88 DF_DA | DF_SETS_CONST,
89
90 // 13 OP_CONST_16 vAA, #+BBBB
91 DF_DA | DF_SETS_CONST,
92
93 // 14 OP_CONST vAA, #+BBBBBBBB
94 DF_DA | DF_SETS_CONST,
95
96 // 15 OP_CONST_HIGH16 VAA, #+BBBB0000
97 DF_DA | DF_SETS_CONST,
98
99 // 16 OP_CONST_WIDE_16 vAA, #+BBBB
100 DF_DA_WIDE | DF_SETS_CONST,
101
102 // 17 OP_CONST_WIDE_32 vAA, #+BBBBBBBB
103 DF_DA_WIDE | DF_SETS_CONST,
104
105 // 18 OP_CONST_WIDE vAA, #+BBBBBBBBBBBBBBBB
106 DF_DA_WIDE | DF_SETS_CONST,
107
108 // 19 OP_CONST_WIDE_HIGH16 vAA, #+BBBB000000000000
109 DF_DA_WIDE | DF_SETS_CONST,
110
111 // 1A OP_CONST_STRING vAA, string@BBBB
buzbee67bc2362011-10-11 18:08:40 -0700112 DF_DA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700113
114 // 1B OP_CONST_STRING_JUMBO vAA, string@BBBBBBBB
buzbee67bc2362011-10-11 18:08:40 -0700115 DF_DA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700116
117 // 1C OP_CONST_CLASS vAA, type@BBBB
buzbee67bc2362011-10-11 18:08:40 -0700118 DF_DA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700119
120 // 1D OP_MONITOR_ENTER vAA
buzbee67bc2362011-10-11 18:08:40 -0700121 DF_UA | DF_NULL_CHK_0 | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700122
123 // 1E OP_MONITOR_EXIT vAA
buzbee67bc2362011-10-11 18:08:40 -0700124 DF_UA | DF_NULL_CHK_0 | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700125
buzbee43a36422011-09-14 14:00:13 -0700126 // 1F OP_CHK_CAST vAA, type@BBBB
buzbee67bc2362011-10-11 18:08:40 -0700127 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700128
129 // 20 OP_INSTANCE_OF vA, vB, type@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700130 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700131
132 // 21 OP_ARRAY_LENGTH vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700133 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700134
135 // 22 OP_NEW_INSTANCE vAA, type@BBBB
buzbee67bc2362011-10-11 18:08:40 -0700136 DF_DA | DF_NON_NULL_DST | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700137
138 // 23 OP_NEW_ARRAY vA, vB, type@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700139 DF_DA | DF_UB | DF_NON_NULL_DST | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700140
141 // 24 OP_FILLED_NEW_ARRAY {vD, vE, vF, vG, vA}
buzbee43a36422011-09-14 14:00:13 -0700142 DF_FORMAT_35C | DF_NON_NULL_RET,
buzbee67bf8852011-08-17 17:51:35 -0700143
144 // 25 OP_FILLED_NEW_ARRAY_RANGE {vCCCC .. vNNNN}, type@BBBB
buzbee43a36422011-09-14 14:00:13 -0700145 DF_FORMAT_3RC | DF_NON_NULL_RET,
buzbee67bf8852011-08-17 17:51:35 -0700146
147 // 26 OP_FILL_ARRAY_DATA vAA, +BBBBBBBB
buzbee67bc2362011-10-11 18:08:40 -0700148 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700149
150 // 27 OP_THROW vAA
buzbee67bc2362011-10-11 18:08:40 -0700151 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700152
153 // 28 OP_GOTO
154 DF_NOP,
155
156 // 29 OP_GOTO_16
157 DF_NOP,
158
159 // 2A OP_GOTO_32
160 DF_NOP,
161
162 // 2B OP_PACKED_SWITCH vAA, +BBBBBBBB
163 DF_UA,
164
165 // 2C OP_SPARSE_SWITCH vAA, +BBBBBBBB
166 DF_UA,
167
168 // 2D OP_CMPL_FLOAT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700169 DF_DA | DF_UB | DF_UC | DF_FP_B | DF_FP_C | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700170
171 // 2E OP_CMPG_FLOAT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700172 DF_DA | DF_UB | DF_UC | DF_FP_B | DF_FP_C | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700173
174 // 2F OP_CMPL_DOUBLE vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700175 DF_DA | DF_UB_WIDE | DF_UC_WIDE | DF_FP_B | DF_FP_C | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700176
177 // 30 OP_CMPG_DOUBLE vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700178 DF_DA | DF_UB_WIDE | DF_UC_WIDE | DF_FP_B | DF_FP_C | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700179
180 // 31 OP_CMP_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700181 DF_DA | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700182
183 // 32 OP_IF_EQ vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700184 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700185
186 // 33 OP_IF_NE vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700187 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700188
189 // 34 OP_IF_LT vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700190 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700191
192 // 35 OP_IF_GE vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700193 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700194
195 // 36 OP_IF_GT vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700196 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700197
198 // 37 OP_IF_LE vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700199 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700200
201
202 // 38 OP_IF_EQZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700203 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700204
205 // 39 OP_IF_NEZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700206 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700207
208 // 3A OP_IF_LTZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700209 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700210
211 // 3B OP_IF_GEZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700212 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700213
214 // 3C OP_IF_GTZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700215 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700216
217 // 3D OP_IF_LEZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700218 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700219
220 // 3E OP_UNUSED_3E
221 DF_NOP,
222
223 // 3F OP_UNUSED_3F
224 DF_NOP,
225
226 // 40 OP_UNUSED_40
227 DF_NOP,
228
229 // 41 OP_UNUSED_41
230 DF_NOP,
231
232 // 42 OP_UNUSED_42
233 DF_NOP,
234
235 // 43 OP_UNUSED_43
236 DF_NOP,
237
238 // 44 OP_AGET vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700239 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_IS_GETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700240
241 // 45 OP_AGET_WIDE vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700242 DF_DA_WIDE | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_IS_GETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700243
244 // 46 OP_AGET_OBJECT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700245 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_IS_GETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700246
247 // 47 OP_AGET_BOOLEAN vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700248 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_IS_GETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700249
250 // 48 OP_AGET_BYTE vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700251 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_IS_GETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700252
253 // 49 OP_AGET_CHAR vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700254 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_IS_GETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700255
256 // 4A OP_AGET_SHORT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700257 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_IS_GETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700258
259 // 4B OP_APUT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700260 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_IS_SETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700261
262 // 4C OP_APUT_WIDE vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700263 DF_UA_WIDE | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_IS_SETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700264
265 // 4D OP_APUT_OBJECT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700266 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_IS_SETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700267
268 // 4E OP_APUT_BOOLEAN vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700269 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_IS_SETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700270
271 // 4F OP_APUT_BYTE vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700272 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_IS_SETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700273
274 // 50 OP_APUT_CHAR vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700275 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_IS_SETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700276
277 // 51 OP_APUT_SHORT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700278 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_IS_SETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700279
280 // 52 OP_IGET vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700281 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700282
283 // 53 OP_IGET_WIDE vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700284 DF_DA_WIDE | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700285
286 // 54 OP_IGET_OBJECT vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700287 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700288
289 // 55 OP_IGET_BOOLEAN vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700290 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700291
292 // 56 OP_IGET_BYTE vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700293 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700294
295 // 57 OP_IGET_CHAR vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700296 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700297
298 // 58 OP_IGET_SHORT vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700299 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700300
301 // 59 OP_IPUT vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700302 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700303
304 // 5A OP_IPUT_WIDE vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700305 DF_UA_WIDE | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700306
307 // 5B OP_IPUT_OBJECT vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700308 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700309
310 // 5C OP_IPUT_BOOLEAN vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700311 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700312
313 // 5D OP_IPUT_BYTE vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700314 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700315
316 // 5E OP_IPUT_CHAR vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700317 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700318
319 // 5F OP_IPUT_SHORT vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700320 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700321
322 // 60 OP_SGET vAA, field@BBBB
323 DF_DA | DF_IS_GETTER,
324
325 // 61 OP_SGET_WIDE vAA, field@BBBB
326 DF_DA_WIDE | DF_IS_GETTER,
327
328 // 62 OP_SGET_OBJECT vAA, field@BBBB
buzbee67bc2362011-10-11 18:08:40 -0700329 DF_DA | DF_IS_GETTER | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700330
331 // 63 OP_SGET_BOOLEAN vAA, field@BBBB
332 DF_DA | DF_IS_GETTER,
333
334 // 64 OP_SGET_BYTE vAA, field@BBBB
335 DF_DA | DF_IS_GETTER,
336
337 // 65 OP_SGET_CHAR vAA, field@BBBB
338 DF_DA | DF_IS_GETTER,
339
340 // 66 OP_SGET_SHORT vAA, field@BBBB
341 DF_DA | DF_IS_GETTER,
342
343 // 67 OP_SPUT vAA, field@BBBB
344 DF_UA | DF_IS_SETTER,
345
346 // 68 OP_SPUT_WIDE vAA, field@BBBB
347 DF_UA_WIDE | DF_IS_SETTER,
348
349 // 69 OP_SPUT_OBJECT vAA, field@BBBB
buzbee67bc2362011-10-11 18:08:40 -0700350 DF_UA | DF_IS_SETTER | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700351
352 // 6A OP_SPUT_BOOLEAN vAA, field@BBBB
353 DF_UA | DF_IS_SETTER,
354
355 // 6B OP_SPUT_BYTE vAA, field@BBBB
356 DF_UA | DF_IS_SETTER,
357
358 // 6C OP_SPUT_CHAR vAA, field@BBBB
359 DF_UA | DF_IS_SETTER,
360
361 // 6D OP_SPUT_SHORT vAA, field@BBBB
362 DF_UA | DF_IS_SETTER,
363
364 // 6E OP_INVOKE_VIRTUAL {vD, vE, vF, vG, vA}
buzbee43a36422011-09-14 14:00:13 -0700365 DF_FORMAT_35C | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700366
367 // 6F OP_INVOKE_SUPER {vD, vE, vF, vG, vA}
buzbee43a36422011-09-14 14:00:13 -0700368 DF_FORMAT_35C | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700369
370 // 70 OP_INVOKE_DIRECT {vD, vE, vF, vG, vA}
buzbee43a36422011-09-14 14:00:13 -0700371 DF_FORMAT_35C | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700372
373 // 71 OP_INVOKE_STATIC {vD, vE, vF, vG, vA}
374 DF_FORMAT_35C,
375
376 // 72 OP_INVOKE_INTERFACE {vD, vE, vF, vG, vA}
377 DF_FORMAT_35C,
378
379 // 73 OP_UNUSED_73
380 DF_NOP,
381
382 // 74 OP_INVOKE_VIRTUAL_RANGE {vCCCC .. vNNNN}
buzbee43a36422011-09-14 14:00:13 -0700383 DF_FORMAT_3RC | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700384
385 // 75 OP_INVOKE_SUPER_RANGE {vCCCC .. vNNNN}
buzbee43a36422011-09-14 14:00:13 -0700386 DF_FORMAT_3RC | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700387
388 // 76 OP_INVOKE_DIRECT_RANGE {vCCCC .. vNNNN}
buzbee43a36422011-09-14 14:00:13 -0700389 DF_FORMAT_3RC | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700390
391 // 77 OP_INVOKE_STATIC_RANGE {vCCCC .. vNNNN}
392 DF_FORMAT_3RC,
393
394 // 78 OP_INVOKE_INTERFACE_RANGE {vCCCC .. vNNNN}
395 DF_FORMAT_3RC,
396
397 // 79 OP_UNUSED_79
398 DF_NOP,
399
400 // 7A OP_UNUSED_7A
401 DF_NOP,
402
403 // 7B OP_NEG_INT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700404 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700405
406 // 7C OP_NOT_INT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700407 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700408
409 // 7D OP_NEG_LONG vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700410 DF_DA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700411
412 // 7E OP_NOT_LONG vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700413 DF_DA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700414
415 // 7F OP_NEG_FLOAT vA, vB
416 DF_DA | DF_UB | DF_FP_A | DF_FP_B,
417
418 // 80 OP_NEG_DOUBLE vA, vB
419 DF_DA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
420
421 // 81 OP_INT_TO_LONG vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700422 DF_DA_WIDE | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700423
424 // 82 OP_INT_TO_FLOAT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700425 DF_DA | DF_UB | DF_FP_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700426
427 // 83 OP_INT_TO_DOUBLE vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700428 DF_DA_WIDE | DF_UB | DF_FP_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700429
430 // 84 OP_LONG_TO_INT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700431 DF_DA | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700432
433 // 85 OP_LONG_TO_FLOAT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700434 DF_DA | DF_UB_WIDE | DF_FP_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700435
436 // 86 OP_LONG_TO_DOUBLE vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700437 DF_DA_WIDE | DF_UB_WIDE | DF_FP_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700438
439 // 87 OP_FLOAT_TO_INT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700440 DF_DA | DF_UB | DF_FP_B | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700441
442 // 88 OP_FLOAT_TO_LONG vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700443 DF_DA_WIDE | DF_UB | DF_FP_B | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700444
445 // 89 OP_FLOAT_TO_DOUBLE vA, vB
446 DF_DA_WIDE | DF_UB | DF_FP_A | DF_FP_B,
447
448 // 8A OP_DOUBLE_TO_INT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700449 DF_DA | DF_UB_WIDE | DF_FP_B | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700450
451 // 8B OP_DOUBLE_TO_LONG vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700452 DF_DA_WIDE | DF_UB_WIDE | DF_FP_B | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700453
454 // 8C OP_DOUBLE_TO_FLOAT vA, vB
455 DF_DA | DF_UB_WIDE | DF_FP_A | DF_FP_B,
456
457 // 8D OP_INT_TO_BYTE vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700458 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700459
460 // 8E OP_INT_TO_CHAR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700461 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700462
463 // 8F OP_INT_TO_SHORT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700464 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700465
466 // 90 OP_ADD_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700467 DF_DA | DF_UB | DF_UC | DF_IS_LINEAR | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700468
469 // 91 OP_SUB_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700470 DF_DA | DF_UB | DF_UC | DF_IS_LINEAR | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700471
472 // 92 OP_MUL_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700473 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700474
475 // 93 OP_DIV_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700476 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700477
478 // 94 OP_REM_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700479 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700480
481 // 95 OP_AND_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700482 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700483
484 // 96 OP_OR_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700485 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700486
487 // 97 OP_XOR_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700488 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700489
490 // 98 OP_SHL_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700491 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700492
493 // 99 OP_SHR_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700494 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700495
496 // 9A OP_USHR_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700497 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700498
499 // 9B OP_ADD_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700500 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700501
502 // 9C OP_SUB_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700503 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700504
505 // 9D OP_MUL_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700506 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700507
508 // 9E OP_DIV_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700509 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700510
511 // 9F OP_REM_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700512 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700513
514 // A0 OP_AND_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700515 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700516
517 // A1 OP_OR_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700518 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700519
520 // A2 OP_XOR_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700521 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700522
523 // A3 OP_SHL_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700524 DF_DA_WIDE | DF_UB_WIDE | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700525
526 // A4 OP_SHR_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700527 DF_DA_WIDE | DF_UB_WIDE | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700528
529 // A5 OP_USHR_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700530 DF_DA_WIDE | DF_UB_WIDE | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700531
532 // A6 OP_ADD_FLOAT vAA, vBB, vCC
533 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
534
535 // A7 OP_SUB_FLOAT vAA, vBB, vCC
536 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
537
538 // A8 OP_MUL_FLOAT vAA, vBB, vCC
539 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
540
541 // A9 OP_DIV_FLOAT vAA, vBB, vCC
542 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
543
544 // AA OP_REM_FLOAT vAA, vBB, vCC
545 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
546
547 // AB OP_ADD_DOUBLE vAA, vBB, vCC
548 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
549
550 // AC OP_SUB_DOUBLE vAA, vBB, vCC
551 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
552
553 // AD OP_MUL_DOUBLE vAA, vBB, vCC
554 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
555
556 // AE OP_DIV_DOUBLE vAA, vBB, vCC
557 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
558
559 // AF OP_REM_DOUBLE vAA, vBB, vCC
560 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
561
562 // B0 OP_ADD_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700563 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700564
565 // B1 OP_SUB_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700566 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700567
568 // B2 OP_MUL_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700569 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700570
571 // B3 OP_DIV_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700572 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700573
574 // B4 OP_REM_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700575 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700576
577 // B5 OP_AND_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700578 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700579
580 // B6 OP_OR_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700581 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700582
583 // B7 OP_XOR_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700584 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700585
586 // B8 OP_SHL_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700587 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700588
589 // B9 OP_SHR_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700590 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700591
592 // BA OP_USHR_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700593 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700594
595 // BB OP_ADD_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700596 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700597
598 // BC OP_SUB_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700599 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700600
601 // BD OP_MUL_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700602 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700603
604 // BE OP_DIV_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700605 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700606
607 // BF OP_REM_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700608 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700609
610 // C0 OP_AND_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700611 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700612
613 // C1 OP_OR_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700614 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700615
616 // C2 OP_XOR_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700617 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700618
619 // C3 OP_SHL_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700620 DF_DA_WIDE | DF_UA_WIDE | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700621
622 // C4 OP_SHR_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700623 DF_DA_WIDE | DF_UA_WIDE | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700624
625 // C5 OP_USHR_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700626 DF_DA_WIDE | DF_UA_WIDE | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700627
628 // C6 OP_ADD_FLOAT_2ADDR vA, vB
629 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
630
631 // C7 OP_SUB_FLOAT_2ADDR vA, vB
632 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
633
634 // C8 OP_MUL_FLOAT_2ADDR vA, vB
635 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
636
637 // C9 OP_DIV_FLOAT_2ADDR vA, vB
638 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
639
640 // CA OP_REM_FLOAT_2ADDR vA, vB
641 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
642
643 // CB OP_ADD_DOUBLE_2ADDR vA, vB
644 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
645
646 // CC OP_SUB_DOUBLE_2ADDR vA, vB
647 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
648
649 // CD OP_MUL_DOUBLE_2ADDR vA, vB
650 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
651
652 // CE OP_DIV_DOUBLE_2ADDR vA, vB
653 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
654
655 // CF OP_REM_DOUBLE_2ADDR vA, vB
656 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
657
658 // D0 OP_ADD_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700659 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700660
661 // D1 OP_RSUB_INT vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700662 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700663
664 // D2 OP_MUL_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700665 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700666
667 // D3 OP_DIV_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700668 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700669
670 // D4 OP_REM_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700671 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700672
673 // D5 OP_AND_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700674 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700675
676 // D6 OP_OR_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700677 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700678
679 // D7 OP_XOR_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700680 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700681
682 // D8 OP_ADD_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700683 DF_DA | DF_UB | DF_IS_LINEAR | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700684
685 // D9 OP_RSUB_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700686 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700687
688 // DA OP_MUL_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700689 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700690
691 // DB OP_DIV_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700692 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700693
694 // DC OP_REM_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700695 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700696
697 // DD OP_AND_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700698 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700699
700 // DE OP_OR_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700701 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700702
703 // DF OP_XOR_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700704 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700705
706 // E0 OP_SHL_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700707 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700708
709 // E1 OP_SHR_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700710 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700711
712 // E2 OP_USHR_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700713 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700714
715 // E3 OP_IGET_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700716 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700717
718 // E4 OP_IPUT_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700719 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700720
721 // E5 OP_SGET_VOLATILE
722 DF_DA,
723
724 // E6 OP_SPUT_VOLATILE
725 DF_UA,
726
727 // E7 OP_IGET_OBJECT_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700728 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700729
730 // E8 OP_IGET_WIDE_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700731 DF_DA_WIDE | DF_UB | DF_NULL_CHK_0 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700732
733 // E9 OP_IPUT_WIDE_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700734 DF_UA_WIDE | DF_UB | DF_NULL_CHK_1 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700735
736 // EA OP_SGET_WIDE_VOLATILE
737 DF_DA_WIDE,
738
739 // EB OP_SPUT_WIDE_VOLATILE
740 DF_UA_WIDE,
741
742 // EC OP_BREAKPOINT
743 DF_NOP,
744
745 // ED OP_THROW_VERIFICATION_ERROR
746 DF_NOP,
747
748 // EE OP_EXECUTE_INLINE
749 DF_FORMAT_35C,
750
751 // EF OP_EXECUTE_INLINE_RANGE
752 DF_FORMAT_3RC,
753
754 // F0 OP_INVOKE_OBJECT_INIT_RANGE
buzbee43a36422011-09-14 14:00:13 -0700755 DF_NOP | DF_NULL_CHK_0,
buzbee67bf8852011-08-17 17:51:35 -0700756
757 // F1 OP_RETURN_VOID_BARRIER
758 DF_NOP,
759
760 // F2 OP_IGET_QUICK
buzbee43a36422011-09-14 14:00:13 -0700761 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER,
buzbee67bf8852011-08-17 17:51:35 -0700762
763 // F3 OP_IGET_WIDE_QUICK
buzbee43a36422011-09-14 14:00:13 -0700764 DF_DA_WIDE | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER,
buzbee67bf8852011-08-17 17:51:35 -0700765
766 // F4 OP_IGET_OBJECT_QUICK
buzbee43a36422011-09-14 14:00:13 -0700767 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER,
buzbee67bf8852011-08-17 17:51:35 -0700768
769 // F5 OP_IPUT_QUICK
buzbee43a36422011-09-14 14:00:13 -0700770 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER,
buzbee67bf8852011-08-17 17:51:35 -0700771
772 // F6 OP_IPUT_WIDE_QUICK
buzbee43a36422011-09-14 14:00:13 -0700773 DF_UA_WIDE | DF_UB | DF_NULL_CHK_1 |DF_IS_SETTER,
buzbee67bf8852011-08-17 17:51:35 -0700774
775 // F7 OP_IPUT_OBJECT_QUICK
buzbee43a36422011-09-14 14:00:13 -0700776 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER,
buzbee67bf8852011-08-17 17:51:35 -0700777
778 // F8 OP_INVOKE_VIRTUAL_QUICK
buzbee43a36422011-09-14 14:00:13 -0700779 DF_FORMAT_35C | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700780
781 // F9 OP_INVOKE_VIRTUAL_QUICK_RANGE
buzbee43a36422011-09-14 14:00:13 -0700782 DF_FORMAT_3RC | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700783
784 // FA OP_INVOKE_SUPER_QUICK
buzbee43a36422011-09-14 14:00:13 -0700785 DF_FORMAT_35C | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700786
787 // FB OP_INVOKE_SUPER_QUICK_RANGE
buzbee43a36422011-09-14 14:00:13 -0700788 DF_FORMAT_3RC | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700789
790 // FC OP_IPUT_OBJECT_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700791 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700792
793 // FD OP_SGET_OBJECT_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700794 DF_DA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700795
796 // FE OP_SPUT_OBJECT_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700797 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700798
Elliott Hughes8e5944b2012-01-05 13:44:44 -0800799 // FF OP_UNUSED_FF
buzbee67bf8852011-08-17 17:51:35 -0700800 DF_NOP,
801
802 // Beginning of extended MIR opcodes
Elliott Hughes8e5944b2012-01-05 13:44:44 -0800803 // 100 OP_MIR_PHI
buzbee43a36422011-09-14 14:00:13 -0700804 DF_PHI | DF_DA | DF_NULL_TRANSFER_N,
buzbee67bf8852011-08-17 17:51:35 -0700805 /*
806 * For extended MIR inserted at the MIR2LIR stage, it is okay to have
807 * undefined values here.
808 */
809};
810
811/* Return the Dalvik register/subscript pair of a given SSA register */
812int oatConvertSSARegToDalvik(const CompilationUnit* cUnit, int ssaReg)
813{
814 return GET_ELEM_N(cUnit->ssaToDalvikMap, int, ssaReg);
815}
816
817/*
818 * Utility function to convert encoded SSA register value into Dalvik register
819 * and subscript pair. Each SSA register can be used to index the
820 * ssaToDalvikMap list to get the subscript[31..16]/dalvik_reg[15..0] mapping.
821 */
buzbeeba938cb2012-02-03 14:47:55 -0800822char* oatGetDalvikDisassembly(CompilationUnit* cUnit,
823 const DecodedInstruction* insn, const char* note)
buzbee67bf8852011-08-17 17:51:35 -0700824{
825 char buffer[256];
826 Opcode opcode = insn->opcode;
827 int dfAttributes = oatDataFlowAttributes[opcode];
828 int flags;
829 char* ret;
830
831 buffer[0] = 0;
832 if ((int)opcode >= (int)kMirOpFirst) {
833 if ((int)opcode == (int)kMirOpPhi) {
834 strcpy(buffer, "PHI");
835 }
836 else {
837 sprintf(buffer, "Opcode %#x", opcode);
838 }
839 flags = 0;
840 } else {
841 strcpy(buffer, dexGetOpcodeName(opcode));
842 flags = dexGetFlagsFromOpcode(insn->opcode);
843 }
844
845 if (note)
846 strcat(buffer, note);
847
848 /* For branches, decode the instructions to print out the branch targets */
849 if (flags & kInstrCanBranch) {
850 InstructionFormat dalvikFormat = dexGetFormatFromOpcode(insn->opcode);
851 int offset = 0;
852 switch (dalvikFormat) {
853 case kFmt21t:
854 snprintf(buffer + strlen(buffer), 256, " v%d,", insn->vA);
855 offset = (int) insn->vB;
856 break;
857 case kFmt22t:
858 snprintf(buffer + strlen(buffer), 256, " v%d, v%d,",
859 insn->vA, insn->vB);
860 offset = (int) insn->vC;
861 break;
862 case kFmt10t:
863 case kFmt20t:
864 case kFmt30t:
865 offset = (int) insn->vA;
866 break;
867 default:
868 LOG(FATAL) << "Unexpected branch format " << (int)dalvikFormat
869 << " / opcode " << (int)opcode;
870 }
871 snprintf(buffer + strlen(buffer), 256, " (%c%x)",
872 offset > 0 ? '+' : '-',
873 offset > 0 ? offset : -offset);
874 } else if (dfAttributes & DF_FORMAT_35C) {
875 unsigned int i;
876 for (i = 0; i < insn->vA; i++) {
877 if (i != 0) strcat(buffer, ",");
878 snprintf(buffer + strlen(buffer), 256, " v%d", insn->arg[i]);
879 }
880 }
881 else if (dfAttributes & DF_FORMAT_3RC) {
882 snprintf(buffer + strlen(buffer), 256,
883 " v%d..v%d", insn->vC, insn->vC + insn->vA - 1);
884 }
885 else {
886 if (dfAttributes & DF_A_IS_REG) {
887 snprintf(buffer + strlen(buffer), 256, " v%d", insn->vA);
888 }
889 if (dfAttributes & DF_B_IS_REG) {
890 snprintf(buffer + strlen(buffer), 256, ", v%d", insn->vB);
891 }
892 else if ((int)opcode < (int)kMirOpFirst) {
893 snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn->vB);
894 }
895 if (dfAttributes & DF_C_IS_REG) {
896 snprintf(buffer + strlen(buffer), 256, ", v%d", insn->vC);
897 }
898 else if ((int)opcode < (int)kMirOpFirst) {
899 snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn->vC);
900 }
901 }
902 int length = strlen(buffer) + 1;
buzbeeba938cb2012-02-03 14:47:55 -0800903 ret = (char*)oatNew(cUnit, length, false, kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -0700904 memcpy(ret, buffer, length);
905 return ret;
906}
907
Elliott Hughesc1f143d2011-12-01 17:31:10 -0800908char* getSSAName(const CompilationUnit* cUnit, int ssaReg, char* name)
buzbee67bf8852011-08-17 17:51:35 -0700909{
910 int ssa2DalvikValue = oatConvertSSARegToDalvik(cUnit, ssaReg);
911
912 sprintf(name, "v%d_%d",
913 DECODE_REG(ssa2DalvikValue), DECODE_SUB(ssa2DalvikValue));
914 return name;
915}
916
917/*
918 * Dalvik instruction disassembler with optional SSA printing.
919 */
buzbee31a4a6f2012-02-28 15:36:15 -0800920char* oatFullDisassembler(CompilationUnit* cUnit, const MIR* mir)
buzbee67bf8852011-08-17 17:51:35 -0700921{
922 char buffer[256];
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700923 char operand0[32], operand1[32];
buzbee67bf8852011-08-17 17:51:35 -0700924 const DecodedInstruction *insn = &mir->dalvikInsn;
925 int opcode = insn->opcode;
926 int dfAttributes = oatDataFlowAttributes[opcode];
Elliott Hughesc1f143d2011-12-01 17:31:10 -0800927 char* ret;
buzbee67bf8852011-08-17 17:51:35 -0700928 int length;
929 OpcodeFlags flags;
930
931 buffer[0] = 0;
932 if (opcode >= kMirOpFirst) {
933 if (opcode == kMirOpPhi) {
934 snprintf(buffer, 256, "PHI %s = (%s",
935 getSSAName(cUnit, mir->ssaRep->defs[0], operand0),
936 getSSAName(cUnit, mir->ssaRep->uses[0], operand1));
937 int i;
938 for (i = 1; i < mir->ssaRep->numUses; i++) {
939 snprintf(buffer + strlen(buffer), 256, ", %s",
940 getSSAName(cUnit, mir->ssaRep->uses[i], operand0));
941 }
942 snprintf(buffer + strlen(buffer), 256, ")");
943 }
944 else {
945 sprintf(buffer, "Opcode %#x", opcode);
946 }
947 goto done;
948 } else {
949 strcpy(buffer, dexGetOpcodeName((Opcode)opcode));
950 }
951
952 flags = dexGetFlagsFromOpcode((Opcode)opcode);
953 /* For branches, decode the instructions to print out the branch targets */
954 if (flags & kInstrCanBranch) {
955 InstructionFormat dalvikFormat = dexGetFormatFromOpcode(insn->opcode);
956 int delta = 0;
957 switch (dalvikFormat) {
958 case kFmt21t:
959 snprintf(buffer + strlen(buffer), 256, " %s, ",
960 getSSAName(cUnit, mir->ssaRep->uses[0], operand0));
961 delta = (int) insn->vB;
962 break;
963 case kFmt22t:
964 snprintf(buffer + strlen(buffer), 256, " %s, %s, ",
965 getSSAName(cUnit, mir->ssaRep->uses[0], operand0),
966 getSSAName(cUnit, mir->ssaRep->uses[1], operand1));
967 delta = (int) insn->vC;
968 break;
969 case kFmt10t:
970 case kFmt20t:
971 case kFmt30t:
972 delta = (int) insn->vA;
973 break;
974 default:
975 LOG(FATAL) << "Unexpected branch format: " <<
976 (int)dalvikFormat;
977 }
978 snprintf(buffer + strlen(buffer), 256, " %04x",
979 mir->offset + delta);
980 } else if (dfAttributes & (DF_FORMAT_35C | DF_FORMAT_3RC)) {
981 unsigned int i;
982 for (i = 0; i < insn->vA; i++) {
983 if (i != 0) strcat(buffer, ",");
984 snprintf(buffer + strlen(buffer), 256, " %s",
985 getSSAName(cUnit, mir->ssaRep->uses[i], operand0));
986 }
987 } else {
988 int udIdx;
989 if (mir->ssaRep->numDefs) {
990
991 for (udIdx = 0; udIdx < mir->ssaRep->numDefs; udIdx++) {
992 snprintf(buffer + strlen(buffer), 256, " %s",
993 getSSAName(cUnit, mir->ssaRep->defs[udIdx], operand0));
994 }
995 strcat(buffer, ",");
996 }
997 if (mir->ssaRep->numUses) {
998 /* No leading ',' for the first use */
999 snprintf(buffer + strlen(buffer), 256, " %s",
1000 getSSAName(cUnit, mir->ssaRep->uses[0], operand0));
1001 for (udIdx = 1; udIdx < mir->ssaRep->numUses; udIdx++) {
1002 snprintf(buffer + strlen(buffer), 256, ", %s",
1003 getSSAName(cUnit, mir->ssaRep->uses[udIdx], operand0));
1004 }
1005 }
1006 if (opcode < kMirOpFirst) {
1007 InstructionFormat dalvikFormat =
1008 dexGetFormatFromOpcode((Opcode)opcode);
1009 switch (dalvikFormat) {
1010 case kFmt11n: // op vA, #+B
1011 case kFmt21s: // op vAA, #+BBBB
1012 case kFmt21h: // op vAA, #+BBBB00000[00000000]
1013 case kFmt31i: // op vAA, #+BBBBBBBB
1014 case kFmt51l: // op vAA, #+BBBBBBBBBBBBBBBB
1015 snprintf(buffer + strlen(buffer), 256, " #%#x", insn->vB);
1016 break;
1017 case kFmt21c: // op vAA, thing@BBBB
1018 case kFmt31c: // op vAA, thing@BBBBBBBB
1019 snprintf(buffer + strlen(buffer), 256, " @%#x", insn->vB);
1020 break;
1021 case kFmt22b: // op vAA, vBB, #+CC
1022 case kFmt22s: // op vA, vB, #+CCCC
1023 snprintf(buffer + strlen(buffer), 256, " #%#x", insn->vC);
1024 break;
1025 case kFmt22c: // op vA, vB, thing@CCCC
1026 case kFmt22cs: // [opt] op vA, vB, field offset CCCC
1027 snprintf(buffer + strlen(buffer), 256, " @%#x", insn->vC);
1028 break;
1029 /* No need for special printing */
1030 default:
1031 break;
1032 }
1033 }
1034 }
1035
1036done:
1037 length = strlen(buffer) + 1;
buzbeeba938cb2012-02-03 14:47:55 -08001038 ret = (char*) oatNew(cUnit, length, false, kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001039 memcpy(ret, buffer, length);
1040 return ret;
1041}
1042
1043/*
1044 * Utility function to convert encoded SSA register value into Dalvik register
1045 * and subscript pair. Each SSA register can be used to index the
1046 * ssaToDalvikMap list to get the subscript[31..16]/dalvik_reg[15..0] mapping.
1047 */
Elliott Hughesc1f143d2011-12-01 17:31:10 -08001048char* oatGetSSAString(CompilationUnit* cUnit, SSARepresentation* ssaRep)
buzbee67bf8852011-08-17 17:51:35 -07001049{
1050 char buffer[256];
1051 char* ret;
1052 int i;
1053
1054 buffer[0] = 0;
1055 for (i = 0; i < ssaRep->numDefs; i++) {
1056 int ssa2DalvikValue = oatConvertSSARegToDalvik(cUnit, ssaRep->defs[i]);
1057
1058 sprintf(buffer + strlen(buffer), "s%d(v%d_%d) ",
1059 ssaRep->defs[i], DECODE_REG(ssa2DalvikValue),
1060 DECODE_SUB(ssa2DalvikValue));
1061 }
1062
1063 if (ssaRep->numDefs) {
1064 strcat(buffer, "<- ");
1065 }
1066
1067 for (i = 0; i < ssaRep->numUses; i++) {
1068 int ssa2DalvikValue = oatConvertSSARegToDalvik(cUnit, ssaRep->uses[i]);
1069 int len = strlen(buffer);
1070
1071 if (snprintf(buffer + len, 250 - len, "s%d(v%d_%d) ",
1072 ssaRep->uses[i], DECODE_REG(ssa2DalvikValue),
1073 DECODE_SUB(ssa2DalvikValue)) >= (250 - len)) {
1074 strcat(buffer, "...");
1075 break;
1076 }
1077 }
1078
1079 int length = strlen(buffer) + 1;
buzbeeba938cb2012-02-03 14:47:55 -08001080 ret = (char*)oatNew(cUnit, length, false, kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001081 memcpy(ret, buffer, length);
1082 return ret;
1083}
1084
1085/* Any register that is used before being defined is considered live-in */
buzbee31a4a6f2012-02-28 15:36:15 -08001086inline void handleLiveInUse(CompilationUnit* cUnit, ArenaBitVector* useV,
1087 ArenaBitVector* defV, ArenaBitVector* liveInV,
1088 int dalvikRegId)
buzbee67bf8852011-08-17 17:51:35 -07001089{
buzbeeba938cb2012-02-03 14:47:55 -08001090 oatSetBit(cUnit, useV, dalvikRegId);
buzbee67bf8852011-08-17 17:51:35 -07001091 if (!oatIsBitSet(defV, dalvikRegId)) {
buzbeeba938cb2012-02-03 14:47:55 -08001092 oatSetBit(cUnit, liveInV, dalvikRegId);
buzbee67bf8852011-08-17 17:51:35 -07001093 }
1094}
1095
1096/* Mark a reg as being defined */
buzbee31a4a6f2012-02-28 15:36:15 -08001097inline void handleDef(CompilationUnit* cUnit, ArenaBitVector* defV,
1098 int dalvikRegId)
buzbee67bf8852011-08-17 17:51:35 -07001099{
buzbeeba938cb2012-02-03 14:47:55 -08001100 oatSetBit(cUnit, defV, dalvikRegId);
buzbee67bf8852011-08-17 17:51:35 -07001101}
1102
1103/*
1104 * Find out live-in variables for natural loops. Variables that are live-in in
1105 * the main loop body are considered to be defined in the entry block.
1106 */
1107bool oatFindLocalLiveIn(CompilationUnit* cUnit, BasicBlock* bb)
1108{
1109 MIR* mir;
1110 ArenaBitVector *useV, *defV, *liveInV;
1111
1112 if (bb->dataFlowInfo == NULL) return false;
1113
1114 useV = bb->dataFlowInfo->useV =
buzbeeba938cb2012-02-03 14:47:55 -08001115 oatAllocBitVector(cUnit, cUnit->numDalvikRegisters, false, kBitMapUse);
buzbee67bf8852011-08-17 17:51:35 -07001116 defV = bb->dataFlowInfo->defV =
buzbeeba938cb2012-02-03 14:47:55 -08001117 oatAllocBitVector(cUnit, cUnit->numDalvikRegisters, false, kBitMapDef);
buzbee67bf8852011-08-17 17:51:35 -07001118 liveInV = bb->dataFlowInfo->liveInV =
buzbeeba938cb2012-02-03 14:47:55 -08001119 oatAllocBitVector(cUnit, cUnit->numDalvikRegisters, false,
1120 kBitMapLiveIn);
buzbee67bf8852011-08-17 17:51:35 -07001121
1122 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1123 int dfAttributes =
1124 oatDataFlowAttributes[mir->dalvikInsn.opcode];
1125 DecodedInstruction *dInsn = &mir->dalvikInsn;
1126
1127 if (dfAttributes & DF_HAS_USES) {
1128 if (dfAttributes & DF_UA) {
buzbeeba938cb2012-02-03 14:47:55 -08001129 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vA);
buzbee67bf8852011-08-17 17:51:35 -07001130 } else if (dfAttributes & DF_UA_WIDE) {
buzbeeba938cb2012-02-03 14:47:55 -08001131 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vA);
1132 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vA+1);
buzbee67bf8852011-08-17 17:51:35 -07001133 }
1134 if (dfAttributes & DF_UB) {
buzbeeba938cb2012-02-03 14:47:55 -08001135 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vB);
buzbee67bf8852011-08-17 17:51:35 -07001136 } else if (dfAttributes & DF_UB_WIDE) {
buzbeeba938cb2012-02-03 14:47:55 -08001137 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vB);
1138 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vB+1);
buzbee67bf8852011-08-17 17:51:35 -07001139 }
1140 if (dfAttributes & DF_UC) {
buzbeeba938cb2012-02-03 14:47:55 -08001141 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vC);
buzbee67bf8852011-08-17 17:51:35 -07001142 } else if (dfAttributes & DF_UC_WIDE) {
buzbeeba938cb2012-02-03 14:47:55 -08001143 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vC);
1144 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vC+1);
buzbee67bf8852011-08-17 17:51:35 -07001145 }
1146 }
buzbee07ce1d72012-02-10 17:22:02 -08001147 if (dfAttributes & DF_FORMAT_35C) {
1148 for (unsigned int i = 0; i < dInsn->vA; i++) {
1149 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->arg[i]);
1150 }
1151 }
1152 if (dfAttributes & DF_FORMAT_3RC) {
1153 for (unsigned int i = 0; i < dInsn->vA; i++) {
1154 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vC+i);
1155 }
1156 }
buzbee67bf8852011-08-17 17:51:35 -07001157 if (dfAttributes & DF_HAS_DEFS) {
buzbeeba938cb2012-02-03 14:47:55 -08001158 handleDef(cUnit, defV, dInsn->vA);
buzbee67bf8852011-08-17 17:51:35 -07001159 if (dfAttributes & DF_DA_WIDE) {
buzbeeba938cb2012-02-03 14:47:55 -08001160 handleDef(cUnit, defV, dInsn->vA+1);
buzbee67bf8852011-08-17 17:51:35 -07001161 }
1162 }
1163 }
1164 return true;
1165}
1166
1167/* Find out the latest SSA register for a given Dalvik register */
buzbee31a4a6f2012-02-28 15:36:15 -08001168void handleSSAUse(CompilationUnit* cUnit, int* uses, int dalvikReg,
1169 int regIndex)
buzbee67bf8852011-08-17 17:51:35 -07001170{
1171 int encodedValue = cUnit->dalvikToSSAMap[dalvikReg];
1172 int ssaReg = DECODE_REG(encodedValue);
1173 uses[regIndex] = ssaReg;
1174}
1175
1176/* Setup a new SSA register for a given Dalvik register */
buzbee31a4a6f2012-02-28 15:36:15 -08001177void handleSSADef(CompilationUnit* cUnit, int* defs, int dalvikReg,
1178 int regIndex)
buzbee67bf8852011-08-17 17:51:35 -07001179{
buzbee67bf8852011-08-17 17:51:35 -07001180 int ssaReg = cUnit->numSSARegs++;
1181 /* Bump up the subscript */
buzbeef0cde542011-09-13 14:55:02 -07001182 int dalvikSub = ++cUnit->SSALastDefs[dalvikReg];
buzbee67bf8852011-08-17 17:51:35 -07001183 int newD2SMapping = ENCODE_REG_SUB(ssaReg, dalvikSub);
1184
1185 cUnit->dalvikToSSAMap[dalvikReg] = newD2SMapping;
1186
1187 int newS2DMapping = ENCODE_REG_SUB(dalvikReg, dalvikSub);
buzbeeba938cb2012-02-03 14:47:55 -08001188 oatInsertGrowableList(cUnit, cUnit->ssaToDalvikMap, newS2DMapping);
buzbee67bf8852011-08-17 17:51:35 -07001189
1190 defs[regIndex] = ssaReg;
1191}
1192
buzbeeec5adf32011-09-11 15:25:43 -07001193/* Look up new SSA names for format_35c instructions */
buzbee31a4a6f2012-02-28 15:36:15 -08001194void dataFlowSSAFormat35C(CompilationUnit* cUnit, MIR* mir)
buzbee67bf8852011-08-17 17:51:35 -07001195{
1196 DecodedInstruction *dInsn = &mir->dalvikInsn;
1197 int numUses = dInsn->vA;
1198 int i;
1199
1200 mir->ssaRep->numUses = numUses;
buzbeeba938cb2012-02-03 14:47:55 -08001201 mir->ssaRep->uses = (int *)oatNew(cUnit, sizeof(int) * numUses, true,
buzbee5abfa3e2012-01-31 17:01:43 -08001202 kAllocDFInfo);
buzbeeed3e9302011-09-23 17:34:19 -07001203 // NOTE: will be filled in during type & size inference pass
buzbeeba938cb2012-02-03 14:47:55 -08001204 mir->ssaRep->fpUse = (bool *)oatNew(cUnit, sizeof(bool) * numUses, true,
buzbee5abfa3e2012-01-31 17:01:43 -08001205 kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001206
1207 for (i = 0; i < numUses; i++) {
1208 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->arg[i], i);
1209 }
1210}
1211
buzbeeec5adf32011-09-11 15:25:43 -07001212/* Look up new SSA names for format_3rc instructions */
buzbee31a4a6f2012-02-28 15:36:15 -08001213void dataFlowSSAFormat3RC(CompilationUnit* cUnit, MIR* mir)
buzbee67bf8852011-08-17 17:51:35 -07001214{
1215 DecodedInstruction *dInsn = &mir->dalvikInsn;
1216 int numUses = dInsn->vA;
1217 int i;
1218
1219 mir->ssaRep->numUses = numUses;
buzbeeba938cb2012-02-03 14:47:55 -08001220 mir->ssaRep->uses = (int *)oatNew(cUnit, sizeof(int) * numUses, true,
buzbee5abfa3e2012-01-31 17:01:43 -08001221 kAllocDFInfo);
buzbeeed3e9302011-09-23 17:34:19 -07001222 // NOTE: will be filled in during type & size inference pass
buzbeeba938cb2012-02-03 14:47:55 -08001223 mir->ssaRep->fpUse = (bool *)oatNew(cUnit, sizeof(bool) * numUses, true,
buzbee5abfa3e2012-01-31 17:01:43 -08001224 kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001225
1226 for (i = 0; i < numUses; i++) {
1227 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC+i, i);
1228 }
1229}
1230
1231/* Entry function to convert a block into SSA representation */
1232bool oatDoSSAConversion(CompilationUnit* cUnit, BasicBlock* bb)
1233{
1234 MIR* mir;
1235
1236 if (bb->dataFlowInfo == NULL) return false;
1237
1238 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1239 mir->ssaRep = (struct SSARepresentation *)
buzbeeba938cb2012-02-03 14:47:55 -08001240 oatNew(cUnit, sizeof(SSARepresentation), true, kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001241
1242 int dfAttributes =
1243 oatDataFlowAttributes[mir->dalvikInsn.opcode];
1244
buzbeef0cde542011-09-13 14:55:02 -07001245 // If not a pseudo-op, note non-leaf or can throw
1246 if (mir->dalvikInsn.opcode < kNumPackedOpcodes) {
1247 int flags = dexGetFlagsFromOpcode(mir->dalvikInsn.opcode);
buzbeecefd1872011-09-09 09:59:52 -07001248
buzbeef0cde542011-09-13 14:55:02 -07001249 if (flags & kInstrCanThrow) {
1250 cUnit->attrs &= ~METHOD_IS_THROW_FREE;
1251 }
buzbeecefd1872011-09-09 09:59:52 -07001252
buzbeef0cde542011-09-13 14:55:02 -07001253 if (flags & kInstrInvoke) {
1254 cUnit->attrs &= ~METHOD_IS_LEAF;
1255 }
buzbeecefd1872011-09-09 09:59:52 -07001256 }
1257
buzbee67bf8852011-08-17 17:51:35 -07001258 int numUses = 0;
1259
1260 if (dfAttributes & DF_FORMAT_35C) {
1261 dataFlowSSAFormat35C(cUnit, mir);
1262 continue;
1263 }
1264
1265 if (dfAttributes & DF_FORMAT_3RC) {
1266 dataFlowSSAFormat3RC(cUnit, mir);
1267 continue;
1268 }
1269
1270 if (dfAttributes & DF_HAS_USES) {
1271 if (dfAttributes & DF_UA) {
1272 numUses++;
1273 } else if (dfAttributes & DF_UA_WIDE) {
1274 numUses += 2;
1275 }
1276 if (dfAttributes & DF_UB) {
1277 numUses++;
1278 } else if (dfAttributes & DF_UB_WIDE) {
1279 numUses += 2;
1280 }
1281 if (dfAttributes & DF_UC) {
1282 numUses++;
1283 } else if (dfAttributes & DF_UC_WIDE) {
1284 numUses += 2;
1285 }
1286 }
1287
1288 if (numUses) {
1289 mir->ssaRep->numUses = numUses;
buzbeeba938cb2012-02-03 14:47:55 -08001290 mir->ssaRep->uses = (int *)oatNew(cUnit, sizeof(int) * numUses,
buzbee5abfa3e2012-01-31 17:01:43 -08001291 false, kAllocDFInfo);
buzbeeba938cb2012-02-03 14:47:55 -08001292 mir->ssaRep->fpUse = (bool *)oatNew(cUnit, sizeof(bool) * numUses,
buzbee5abfa3e2012-01-31 17:01:43 -08001293 false, kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001294 }
1295
1296 int numDefs = 0;
1297
1298 if (dfAttributes & DF_HAS_DEFS) {
1299 numDefs++;
1300 if (dfAttributes & DF_DA_WIDE) {
1301 numDefs++;
1302 }
1303 }
1304
1305 if (numDefs) {
1306 mir->ssaRep->numDefs = numDefs;
buzbeeba938cb2012-02-03 14:47:55 -08001307 mir->ssaRep->defs = (int *)oatNew(cUnit, sizeof(int) * numDefs,
buzbee5abfa3e2012-01-31 17:01:43 -08001308 false, kAllocDFInfo);
buzbeeba938cb2012-02-03 14:47:55 -08001309 mir->ssaRep->fpDef = (bool *)oatNew(cUnit, sizeof(bool) * numDefs,
buzbee5abfa3e2012-01-31 17:01:43 -08001310 false, kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001311 }
1312
1313 DecodedInstruction *dInsn = &mir->dalvikInsn;
1314
1315 if (dfAttributes & DF_HAS_USES) {
1316 numUses = 0;
1317 if (dfAttributes & DF_UA) {
1318 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
1319 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA, numUses++);
1320 } else if (dfAttributes & DF_UA_WIDE) {
1321 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
1322 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA, numUses++);
1323 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
1324 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA+1, numUses++);
1325 }
1326 if (dfAttributes & DF_UB) {
1327 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
1328 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB, numUses++);
1329 } else if (dfAttributes & DF_UB_WIDE) {
1330 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
1331 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB, numUses++);
1332 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
1333 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB+1, numUses++);
1334 }
1335 if (dfAttributes & DF_UC) {
1336 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
1337 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC, numUses++);
1338 } else if (dfAttributes & DF_UC_WIDE) {
1339 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
1340 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC, numUses++);
1341 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
1342 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC+1, numUses++);
1343 }
1344 }
1345 if (dfAttributes & DF_HAS_DEFS) {
1346 mir->ssaRep->fpDef[0] = dfAttributes & DF_FP_A;
1347 handleSSADef(cUnit, mir->ssaRep->defs, dInsn->vA, 0);
1348 if (dfAttributes & DF_DA_WIDE) {
1349 mir->ssaRep->fpDef[1] = dfAttributes & DF_FP_A;
1350 handleSSADef(cUnit, mir->ssaRep->defs, dInsn->vA+1, 1);
1351 }
1352 }
1353 }
1354
buzbee5abfa3e2012-01-31 17:01:43 -08001355 if (!cUnit->disableDataflow) {
1356 /*
1357 * Take a snapshot of Dalvik->SSA mapping at the end of each block. The
1358 * input to PHI nodes can be derived from the snapshot of all
1359 * predecessor blocks.
1360 */
1361 bb->dataFlowInfo->dalvikToSSAMap =
buzbeeba938cb2012-02-03 14:47:55 -08001362 (int *)oatNew(cUnit, sizeof(int) * cUnit->numDalvikRegisters, false,
buzbee5abfa3e2012-01-31 17:01:43 -08001363 kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001364
buzbee5abfa3e2012-01-31 17:01:43 -08001365 memcpy(bb->dataFlowInfo->dalvikToSSAMap, cUnit->dalvikToSSAMap,
1366 sizeof(int) * cUnit->numDalvikRegisters);
1367 }
buzbee67bf8852011-08-17 17:51:35 -07001368 return true;
1369}
1370
1371/* Setup a constant value for opcodes thare have the DF_SETS_CONST attribute */
buzbee31a4a6f2012-02-28 15:36:15 -08001372void setConstant(CompilationUnit* cUnit, int ssaReg, int value)
buzbee67bf8852011-08-17 17:51:35 -07001373{
buzbeeba938cb2012-02-03 14:47:55 -08001374 oatSetBit(cUnit, cUnit->isConstantV, ssaReg);
buzbee67bf8852011-08-17 17:51:35 -07001375 cUnit->constantValues[ssaReg] = value;
1376}
1377
1378bool oatDoConstantPropagation(CompilationUnit* cUnit, BasicBlock* bb)
1379{
1380 MIR* mir;
1381 ArenaBitVector *isConstantV = cUnit->isConstantV;
1382
1383 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1384 int dfAttributes =
1385 oatDataFlowAttributes[mir->dalvikInsn.opcode];
1386
1387 DecodedInstruction *dInsn = &mir->dalvikInsn;
1388
1389 if (!(dfAttributes & DF_HAS_DEFS)) continue;
1390
1391 /* Handle instructions that set up constants directly */
1392 if (dfAttributes & DF_SETS_CONST) {
1393 if (dfAttributes & DF_DA) {
1394 switch (dInsn->opcode) {
1395 case OP_CONST_4:
1396 case OP_CONST_16:
1397 case OP_CONST:
1398 setConstant(cUnit, mir->ssaRep->defs[0], dInsn->vB);
1399 break;
1400 case OP_CONST_HIGH16:
1401 setConstant(cUnit, mir->ssaRep->defs[0],
1402 dInsn->vB << 16);
1403 break;
1404 default:
1405 break;
1406 }
1407 } else if (dfAttributes & DF_DA_WIDE) {
1408 switch (dInsn->opcode) {
1409 case OP_CONST_WIDE_16:
1410 case OP_CONST_WIDE_32:
1411 setConstant(cUnit, mir->ssaRep->defs[0], dInsn->vB);
1412 setConstant(cUnit, mir->ssaRep->defs[1], 0);
1413 break;
1414 case OP_CONST_WIDE:
1415 setConstant(cUnit, mir->ssaRep->defs[0],
1416 (int) dInsn->vB_wide);
1417 setConstant(cUnit, mir->ssaRep->defs[1],
1418 (int) (dInsn->vB_wide >> 32));
1419 break;
1420 case OP_CONST_WIDE_HIGH16:
1421 setConstant(cUnit, mir->ssaRep->defs[0], 0);
1422 setConstant(cUnit, mir->ssaRep->defs[1],
1423 dInsn->vB << 16);
1424 break;
1425 default:
1426 break;
1427 }
1428 }
1429 /* Handle instructions that set up constants directly */
1430 } else if (dfAttributes & DF_IS_MOVE) {
1431 int i;
1432
1433 for (i = 0; i < mir->ssaRep->numUses; i++) {
1434 if (!oatIsBitSet(isConstantV, mir->ssaRep->uses[i])) break;
1435 }
1436 /* Move a register holding a constant to another register */
1437 if (i == mir->ssaRep->numUses) {
1438 setConstant(cUnit, mir->ssaRep->defs[0],
1439 cUnit->constantValues[mir->ssaRep->uses[0]]);
1440 if (dfAttributes & DF_DA_WIDE) {
1441 setConstant(cUnit, mir->ssaRep->defs[1],
1442 cUnit->constantValues[mir->ssaRep->uses[1]]);
1443 }
1444 }
1445 }
1446 }
1447 /* TODO: implement code to handle arithmetic operations */
1448 return true;
1449}
1450
1451/* Setup the basic data structures for SSA conversion */
1452void oatInitializeSSAConversion(CompilationUnit* cUnit)
1453{
1454 int i;
Ian Rogersa3760aa2011-11-14 14:32:37 -08001455 int numDalvikReg = cUnit->numDalvikRegisters;
buzbee67bf8852011-08-17 17:51:35 -07001456
buzbeeba938cb2012-02-03 14:47:55 -08001457 cUnit->ssaToDalvikMap = (GrowableList *)oatNew(cUnit, sizeof(GrowableList),
buzbee5abfa3e2012-01-31 17:01:43 -08001458 false, kAllocDFInfo);
1459 // Create the SSAtoDalvikMap, estimating the max size
buzbeeba938cb2012-02-03 14:47:55 -08001460 oatInitGrowableList(cUnit, cUnit->ssaToDalvikMap,
buzbee5abfa3e2012-01-31 17:01:43 -08001461 numDalvikReg + cUnit->defCount + 128,
1462 kListSSAtoDalvikMap);
buzbee67bf8852011-08-17 17:51:35 -07001463 /*
1464 * Initial number of SSA registers is equal to the number of Dalvik
1465 * registers.
1466 */
1467 cUnit->numSSARegs = numDalvikReg;
1468
1469 /*
1470 * Initialize the SSA2Dalvik map list. For the first numDalvikReg elements,
1471 * the subscript is 0 so we use the ENCODE_REG_SUB macro to encode the value
1472 * into "(0 << 16) | i"
1473 */
1474 for (i = 0; i < numDalvikReg; i++) {
buzbeeba938cb2012-02-03 14:47:55 -08001475 oatInsertGrowableList(cUnit, cUnit->ssaToDalvikMap,
1476 ENCODE_REG_SUB(i, 0));
buzbee67bf8852011-08-17 17:51:35 -07001477 }
1478
1479 /*
1480 * Initialize the DalvikToSSAMap map. The low 16 bit is the SSA register id,
1481 * while the high 16 bit is the current subscript. The original Dalvik
1482 * register N is mapped to SSA register N with subscript 0.
1483 */
buzbeeba938cb2012-02-03 14:47:55 -08001484 cUnit->dalvikToSSAMap = (int *)oatNew(cUnit, sizeof(int) * numDalvikReg,
buzbee5abfa3e2012-01-31 17:01:43 -08001485 false, kAllocDFInfo);
buzbeef0cde542011-09-13 14:55:02 -07001486 /* Keep track of the higest def for each dalvik reg */
buzbeeba938cb2012-02-03 14:47:55 -08001487 cUnit->SSALastDefs = (int *)oatNew(cUnit, sizeof(int) * numDalvikReg,
buzbee5abfa3e2012-01-31 17:01:43 -08001488 false, kAllocDFInfo);
buzbeef0cde542011-09-13 14:55:02 -07001489
buzbee67bf8852011-08-17 17:51:35 -07001490 for (i = 0; i < numDalvikReg; i++) {
1491 cUnit->dalvikToSSAMap[i] = i;
buzbeef0cde542011-09-13 14:55:02 -07001492 cUnit->SSALastDefs[i] = 0;
buzbee67bf8852011-08-17 17:51:35 -07001493 }
1494
1495 /*
1496 * Allocate the BasicBlockDataFlow structure for the entry and code blocks
1497 */
1498 GrowableListIterator iterator;
1499
1500 oatGrowableListIteratorInit(&cUnit->blockList, &iterator);
1501
1502 while (true) {
1503 BasicBlock* bb = (BasicBlock *) oatGrowableListIteratorNext(&iterator);
1504 if (bb == NULL) break;
1505 if (bb->hidden == true) continue;
1506 if (bb->blockType == kDalvikByteCode ||
1507 bb->blockType == kEntryBlock ||
1508 bb->blockType == kExitBlock) {
1509 bb->dataFlowInfo = (BasicBlockDataFlow *)
buzbeeba938cb2012-02-03 14:47:55 -08001510 oatNew(cUnit, sizeof(BasicBlockDataFlow),
buzbee5abfa3e2012-01-31 17:01:43 -08001511 true, kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001512 }
1513 }
1514}
1515
1516/* Clear the visited flag for each BB */
buzbee31a4a6f2012-02-28 15:36:15 -08001517bool oatClearVisitedFlag(struct CompilationUnit* cUnit, struct BasicBlock* bb)
buzbee67bf8852011-08-17 17:51:35 -07001518{
1519 bb->visited = false;
1520 return true;
1521}
1522
1523void oatDataFlowAnalysisDispatcher(CompilationUnit* cUnit,
1524 bool (*func)(CompilationUnit*, BasicBlock*),
1525 DataFlowAnalysisMode dfaMode,
1526 bool isIterative)
1527{
1528 bool change = true;
1529
1530 while (change) {
1531 change = false;
1532
buzbee5b537102012-01-17 17:33:47 -08001533 switch (dfaMode) {
buzbee67bf8852011-08-17 17:51:35 -07001534 /* Scan all blocks and perform the operations specified in func */
buzbee5b537102012-01-17 17:33:47 -08001535 case kAllNodes:
1536 {
1537 GrowableListIterator iterator;
1538 oatGrowableListIteratorInit(&cUnit->blockList, &iterator);
1539 while (true) {
1540 BasicBlock* bb =
1541 (BasicBlock *) oatGrowableListIteratorNext(&iterator);
1542 if (bb == NULL) break;
1543 if (bb->hidden == true) continue;
1544 change |= (*func)(cUnit, bb);
1545 }
buzbee67bf8852011-08-17 17:51:35 -07001546 }
buzbee5b537102012-01-17 17:33:47 -08001547 break;
1548 /* Scan reachable blocks and perform the ops specified in func. */
1549 case kReachableNodes:
1550 {
1551 int numReachableBlocks = cUnit->numReachableBlocks;
1552 int idx;
1553 const GrowableList *blockList = &cUnit->blockList;
buzbee67bf8852011-08-17 17:51:35 -07001554
buzbee5b537102012-01-17 17:33:47 -08001555 for (idx = 0; idx < numReachableBlocks; idx++) {
1556 int blockIdx = cUnit->dfsOrder.elemList[idx];
1557 BasicBlock* bb =
1558 (BasicBlock *) oatGrowableListGetElement(blockList,
1559 blockIdx);
1560 change |= (*func)(cUnit, bb);
1561 }
buzbee67bf8852011-08-17 17:51:35 -07001562 }
buzbee5b537102012-01-17 17:33:47 -08001563 break;
buzbee67bf8852011-08-17 17:51:35 -07001564
buzbee5b537102012-01-17 17:33:47 -08001565 /* Scan reachable blocks by pre-order dfs and invoke func on each. */
1566 case kPreOrderDFSTraversal:
1567 {
1568 int numReachableBlocks = cUnit->numReachableBlocks;
1569 int idx;
1570 const GrowableList *blockList = &cUnit->blockList;
buzbee67bf8852011-08-17 17:51:35 -07001571
buzbee5b537102012-01-17 17:33:47 -08001572 for (idx = 0; idx < numReachableBlocks; idx++) {
1573 int dfsIdx = cUnit->dfsOrder.elemList[idx];
1574 BasicBlock* bb =
1575 (BasicBlock *) oatGrowableListGetElement(blockList,
1576 dfsIdx);
1577 change |= (*func)(cUnit, bb);
1578 }
buzbee67bf8852011-08-17 17:51:35 -07001579 }
buzbee5b537102012-01-17 17:33:47 -08001580 break;
1581 /* Scan reachable blocks post-order dfs and invoke func on each. */
1582 case kPostOrderDFSTraversal:
1583 {
1584 int numReachableBlocks = cUnit->numReachableBlocks;
1585 int idx;
1586 const GrowableList *blockList = &cUnit->blockList;
buzbee67bf8852011-08-17 17:51:35 -07001587
buzbee5b537102012-01-17 17:33:47 -08001588 for (idx = numReachableBlocks - 1; idx >= 0; idx--) {
1589 int dfsIdx = cUnit->dfsOrder.elemList[idx];
1590 BasicBlock* bb =
1591 (BasicBlock *) oatGrowableListGetElement(blockList,
1592 dfsIdx);
1593 change |= (*func)(cUnit, bb);
1594 }
buzbee67bf8852011-08-17 17:51:35 -07001595 }
buzbee5b537102012-01-17 17:33:47 -08001596 break;
1597 /* Scan reachable post-order dom tree and invoke func on each. */
1598 case kPostOrderDOMTraversal:
1599 {
1600 int numReachableBlocks = cUnit->numReachableBlocks;
1601 int idx;
1602 const GrowableList *blockList = &cUnit->blockList;
1603
1604 for (idx = 0; idx < numReachableBlocks; idx++) {
1605 int domIdx = cUnit->domPostOrderTraversal.elemList[idx];
1606 BasicBlock* bb =
1607 (BasicBlock *) oatGrowableListGetElement(blockList,
1608 domIdx);
1609 change |= (*func)(cUnit, bb);
1610 }
1611 }
1612 break;
1613 /* Scan reachable blocks reverse post-order dfs, invoke func on each */
1614 case kReversePostOrderTraversal:
1615 {
1616 int numReachableBlocks = cUnit->numReachableBlocks;
1617 int idx;
1618 const GrowableList *blockList = &cUnit->blockList;
1619
1620 for (idx = numReachableBlocks - 1; idx >= 0; idx--) {
1621 int revIdx = cUnit->dfsPostOrder.elemList[idx];
1622 BasicBlock* bb =
1623 (BasicBlock *) oatGrowableListGetElement(blockList,
1624 revIdx);
1625 change |= (*func)(cUnit, bb);
1626 }
1627 }
1628 break;
1629 default:
1630 LOG(FATAL) << "Unknown traversal mode " << (int)dfaMode;
buzbee67bf8852011-08-17 17:51:35 -07001631 }
1632 /* If isIterative is false, exit the loop after the first iteration */
1633 change &= isIterative;
1634 }
1635}
buzbee43a36422011-09-14 14:00:13 -07001636
buzbee31a4a6f2012-02-28 15:36:15 -08001637bool nullCheckEliminationInit(struct CompilationUnit* cUnit,
1638 struct BasicBlock* bb)
buzbee43a36422011-09-14 14:00:13 -07001639{
1640 if (bb->dataFlowInfo == NULL) return false;
1641 bb->dataFlowInfo->endingNullCheckV =
buzbeeba938cb2012-02-03 14:47:55 -08001642 oatAllocBitVector(cUnit, cUnit->numSSARegs, false, kBitMapNullCheck);
buzbee43a36422011-09-14 14:00:13 -07001643 oatClearAllBits(bb->dataFlowInfo->endingNullCheckV);
1644 return true;
1645}
1646
1647/* Eliminate unnecessary null checks for a basic block. */
buzbee31a4a6f2012-02-28 15:36:15 -08001648bool eliminateNullChecks( struct CompilationUnit* cUnit, struct BasicBlock* bb)
buzbee43a36422011-09-14 14:00:13 -07001649{
1650 if (bb->dataFlowInfo == NULL) return false;
buzbee5abfa3e2012-01-31 17:01:43 -08001651
buzbee43a36422011-09-14 14:00:13 -07001652 /*
1653 * Set initial state. Be conservative with catch
1654 * blocks and start with no assumptions about null check
1655 * status (except for "this").
1656 */
buzbee43a36422011-09-14 14:00:13 -07001657 if ((bb->blockType == kEntryBlock) | bb->catchEntry) {
1658 oatClearAllBits(cUnit->tempSSARegisterV);
Elliott Hughes11d1b0c2012-01-23 16:57:47 -08001659 if ((cUnit->access_flags & kAccStatic) == 0) {
buzbee43a36422011-09-14 14:00:13 -07001660 // If non-static method, mark "this" as non-null
Ian Rogersa3760aa2011-11-14 14:32:37 -08001661 int thisReg = cUnit->numDalvikRegisters - cUnit->numIns;
buzbeeba938cb2012-02-03 14:47:55 -08001662 oatSetBit(cUnit, cUnit->tempSSARegisterV, thisReg);
buzbee43a36422011-09-14 14:00:13 -07001663 }
1664 } else {
1665 // Starting state is intesection of all incoming arcs
buzbee5abfa3e2012-01-31 17:01:43 -08001666 GrowableListIterator iter;
1667 oatGrowableListIteratorInit(bb->predecessors, &iter);
1668 BasicBlock* predBB = (BasicBlock*)oatGrowableListIteratorNext(&iter);
1669 DCHECK(predBB != NULL);
buzbee43a36422011-09-14 14:00:13 -07001670 oatCopyBitVector(cUnit->tempSSARegisterV,
1671 predBB->dataFlowInfo->endingNullCheckV);
1672 while (true) {
buzbee5abfa3e2012-01-31 17:01:43 -08001673 predBB = (BasicBlock*)oatGrowableListIteratorNext(&iter);
1674 if (!predBB) break;
buzbeeaad72012011-09-21 21:52:09 -07001675 if ((predBB->dataFlowInfo == NULL) ||
1676 (predBB->dataFlowInfo->endingNullCheckV == NULL)) {
1677 continue;
1678 }
buzbee43a36422011-09-14 14:00:13 -07001679 oatIntersectBitVectors(cUnit->tempSSARegisterV,
1680 cUnit->tempSSARegisterV,
1681 predBB->dataFlowInfo->endingNullCheckV);
1682 }
1683 }
1684
1685 // Walk through the instruction in the block, updating as necessary
1686 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1687 if (mir->ssaRep == NULL) {
1688 continue;
1689 }
1690 int dfAttributes =
1691 oatDataFlowAttributes[mir->dalvikInsn.opcode];
1692
1693 // Mark target of NEW* as non-null
1694 if (dfAttributes & DF_NON_NULL_DST) {
buzbeeba938cb2012-02-03 14:47:55 -08001695 oatSetBit(cUnit, cUnit->tempSSARegisterV, mir->ssaRep->defs[0]);
buzbee43a36422011-09-14 14:00:13 -07001696 }
1697
1698 // Mark non-null returns from invoke-style NEW*
1699 if (dfAttributes & DF_NON_NULL_RET) {
1700 MIR* nextMir = mir->next;
1701 // Next should be an OP_MOVE_RESULT_OBJECT
1702 if (nextMir && nextMir->dalvikInsn.opcode == OP_MOVE_RESULT_OBJECT) {
1703 // Mark as null checked
buzbeeba938cb2012-02-03 14:47:55 -08001704 oatSetBit(cUnit, cUnit->tempSSARegisterV,
1705 nextMir->ssaRep->defs[0]);
buzbee43a36422011-09-14 14:00:13 -07001706 } else {
1707 if (nextMir) {
1708 LOG(WARNING) << "Unexpected opcode following new: " <<
1709 (int)nextMir->dalvikInsn.opcode;
buzbee949f56e2011-10-06 11:05:45 -07001710 } else if (bb->fallThrough) {
1711 // Look in next basic block
1712 struct BasicBlock* nextBB = bb->fallThrough;
1713 for (MIR* tmir = nextBB->firstMIRInsn; tmir;
1714 tmir =tmir->next){
1715 if ((int)tmir->dalvikInsn.opcode >= (int)kMirOpFirst) {
1716 continue;
1717 }
1718 // First non-pseudo should be OP_MOVE_RESULT_OBJECT
1719 if (tmir->dalvikInsn.opcode == OP_MOVE_RESULT_OBJECT) {
1720 // Mark as null checked
buzbeeba938cb2012-02-03 14:47:55 -08001721 oatSetBit(cUnit, cUnit->tempSSARegisterV,
buzbee949f56e2011-10-06 11:05:45 -07001722 tmir->ssaRep->defs[0]);
1723 } else {
1724 LOG(WARNING) << "Unexpected op after new: " <<
1725 (int)tmir->dalvikInsn.opcode;
1726 }
1727 break;
1728 }
buzbee43a36422011-09-14 14:00:13 -07001729 }
1730 }
1731 }
1732
1733 /*
1734 * Propagate nullcheck state on register copies (including
1735 * Phi pseudo copies. For the latter, nullcheck state is
1736 * the "and" of all the Phi's operands.
1737 */
1738 if (dfAttributes & (DF_NULL_TRANSFER_0 | DF_NULL_TRANSFER_N)) {
1739 int tgtSreg = mir->ssaRep->defs[0];
1740 int operands = (dfAttributes & DF_NULL_TRANSFER_0) ? 1 :
1741 mir->ssaRep->numUses;
1742 bool nullChecked = true;
1743 for (int i = 0; i < operands; i++) {
1744 nullChecked &= oatIsBitSet(cUnit->tempSSARegisterV,
1745 mir->ssaRep->uses[i]);
1746 }
1747 if (nullChecked) {
buzbeeba938cb2012-02-03 14:47:55 -08001748 oatSetBit(cUnit, cUnit->tempSSARegisterV, tgtSreg);
buzbee43a36422011-09-14 14:00:13 -07001749 }
1750 }
1751
1752 // Already nullchecked?
1753 if (dfAttributes & DF_HAS_NULL_CHKS) {
1754 int srcSreg = (dfAttributes & DF_NULL_CHK_1) ?
1755 mir->ssaRep->uses[1] : mir->ssaRep->uses[0];
1756 if (oatIsBitSet(cUnit->tempSSARegisterV, srcSreg)) {
1757 // Eliminate the null check
1758 mir->optimizationFlags |= MIR_IGNORE_NULL_CHECK;
1759 } else {
1760 // Mark sReg as null-checked
buzbeeba938cb2012-02-03 14:47:55 -08001761 oatSetBit(cUnit, cUnit->tempSSARegisterV, srcSreg);
buzbee43a36422011-09-14 14:00:13 -07001762 }
1763 }
1764 }
1765
1766 // Did anything change?
1767 bool res = oatCompareBitVectors(bb->dataFlowInfo->endingNullCheckV,
1768 cUnit->tempSSARegisterV);
1769 if (res) {
1770 oatCopyBitVector(bb->dataFlowInfo->endingNullCheckV,
1771 cUnit->tempSSARegisterV);
1772 }
1773 return res;
1774}
1775
1776void oatMethodNullCheckElimination(CompilationUnit *cUnit)
1777{
1778 if (!(cUnit->disableOpt & (1 << kNullCheckElimination))) {
1779 DCHECK(cUnit->tempSSARegisterV != NULL);
1780 oatDataFlowAnalysisDispatcher(cUnit, nullCheckEliminationInit,
1781 kAllNodes,
1782 false /* isIterative */);
1783 oatDataFlowAnalysisDispatcher(cUnit, eliminateNullChecks,
1784 kPreOrderDFSTraversal,
1785 true /* isIterative */);
1786 }
1787}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -08001788
1789} // namespace art