blob: 72e3dc47001c360c6d76beac56fc3a8514adae01 [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"
buzbee67bf8852011-08-17 17:51:35 -070019
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080020namespace art {
21
buzbee67bf8852011-08-17 17:51:35 -070022/*
23 * Main table containing data flow attributes for each bytecode. The
24 * first kNumPackedOpcodes entries are for Dalvik bytecode
25 * instructions, where extended opcode at the MIR level are appended
26 * afterwards.
27 *
28 * TODO - many optimization flags are incomplete - they will only limit the
29 * scope of optimizations but will not cause mis-optimizations.
30 */
buzbeeba938cb2012-02-03 14:47:55 -080031const int oatDataFlowAttributes[kMirOpLast] = {
Elliott Hughesadb8c672012-03-06 16:49:32 -080032 // 00 NOP
buzbee67bf8852011-08-17 17:51:35 -070033 DF_NOP,
34
Elliott Hughesadb8c672012-03-06 16:49:32 -080035 // 01 MOVE vA, vB
buzbee67bf8852011-08-17 17:51:35 -070036 DF_DA | DF_UB | DF_IS_MOVE,
37
Elliott Hughesadb8c672012-03-06 16:49:32 -080038 // 02 MOVE_FROM16 vAA, vBBBB
buzbee67bf8852011-08-17 17:51:35 -070039 DF_DA | DF_UB | DF_IS_MOVE,
40
Elliott Hughesadb8c672012-03-06 16:49:32 -080041 // 03 MOVE_16 vAAAA, vBBBB
buzbee67bf8852011-08-17 17:51:35 -070042 DF_DA | DF_UB | DF_IS_MOVE,
43
Elliott Hughesadb8c672012-03-06 16:49:32 -080044 // 04 MOVE_WIDE vA, vB
buzbee67bf8852011-08-17 17:51:35 -070045 DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
46
Elliott Hughesadb8c672012-03-06 16:49:32 -080047 // 05 MOVE_WIDE_FROM16 vAA, vBBBB
buzbee67bf8852011-08-17 17:51:35 -070048 DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
49
Elliott Hughesadb8c672012-03-06 16:49:32 -080050 // 06 MOVE_WIDE_16 vAAAA, vBBBB
buzbee67bf8852011-08-17 17:51:35 -070051 DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
52
Elliott Hughesadb8c672012-03-06 16:49:32 -080053 // 07 MOVE_OBJECT vA, vB
buzbee67bc2362011-10-11 18:08:40 -070054 DF_DA | DF_UB | DF_NULL_TRANSFER_0 | DF_IS_MOVE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -070055
Elliott Hughesadb8c672012-03-06 16:49:32 -080056 // 08 MOVE_OBJECT_FROM16 vAA, vBBBB
buzbee67bc2362011-10-11 18:08:40 -070057 DF_DA | DF_UB | DF_NULL_TRANSFER_0 | DF_IS_MOVE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -070058
Elliott Hughesadb8c672012-03-06 16:49:32 -080059 // 09 MOVE_OBJECT_16 vAAAA, vBBBB
buzbee67bc2362011-10-11 18:08:40 -070060 DF_DA | DF_UB | DF_NULL_TRANSFER_0 | DF_IS_MOVE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -070061
Elliott Hughesadb8c672012-03-06 16:49:32 -080062 // 0A MOVE_RESULT vAA
buzbee67bf8852011-08-17 17:51:35 -070063 DF_DA,
64
Elliott Hughesadb8c672012-03-06 16:49:32 -080065 // 0B MOVE_RESULT_WIDE vAA
buzbee67bf8852011-08-17 17:51:35 -070066 DF_DA_WIDE,
67
Elliott Hughesadb8c672012-03-06 16:49:32 -080068 // 0C MOVE_RESULT_OBJECT vAA
buzbee67bc2362011-10-11 18:08:40 -070069 DF_DA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -070070
Elliott Hughesadb8c672012-03-06 16:49:32 -080071 // 0D MOVE_EXCEPTION vAA
buzbee67bc2362011-10-11 18:08:40 -070072 DF_DA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -070073
Elliott Hughesadb8c672012-03-06 16:49:32 -080074 // 0E RETURN_VOID
buzbee67bf8852011-08-17 17:51:35 -070075 DF_NOP,
76
Elliott Hughesadb8c672012-03-06 16:49:32 -080077 // 0F RETURN vAA
buzbee67bf8852011-08-17 17:51:35 -070078 DF_UA,
79
Elliott Hughesadb8c672012-03-06 16:49:32 -080080 // 10 RETURN_WIDE vAA
buzbee67bf8852011-08-17 17:51:35 -070081 DF_UA_WIDE,
82
Elliott Hughesadb8c672012-03-06 16:49:32 -080083 // 11 RETURN_OBJECT vAA
buzbee67bc2362011-10-11 18:08:40 -070084 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -070085
Elliott Hughesadb8c672012-03-06 16:49:32 -080086 // 12 CONST_4 vA, #+B
buzbee67bf8852011-08-17 17:51:35 -070087 DF_DA | DF_SETS_CONST,
88
Elliott Hughesadb8c672012-03-06 16:49:32 -080089 // 13 CONST_16 vAA, #+BBBB
buzbee67bf8852011-08-17 17:51:35 -070090 DF_DA | DF_SETS_CONST,
91
Elliott Hughesadb8c672012-03-06 16:49:32 -080092 // 14 CONST vAA, #+BBBBBBBB
buzbee67bf8852011-08-17 17:51:35 -070093 DF_DA | DF_SETS_CONST,
94
Elliott Hughesadb8c672012-03-06 16:49:32 -080095 // 15 CONST_HIGH16 VAA, #+BBBB0000
buzbee67bf8852011-08-17 17:51:35 -070096 DF_DA | DF_SETS_CONST,
97
Elliott Hughesadb8c672012-03-06 16:49:32 -080098 // 16 CONST_WIDE_16 vAA, #+BBBB
buzbee67bf8852011-08-17 17:51:35 -070099 DF_DA_WIDE | DF_SETS_CONST,
100
Elliott Hughesadb8c672012-03-06 16:49:32 -0800101 // 17 CONST_WIDE_32 vAA, #+BBBBBBBB
buzbee67bf8852011-08-17 17:51:35 -0700102 DF_DA_WIDE | DF_SETS_CONST,
103
Elliott Hughesadb8c672012-03-06 16:49:32 -0800104 // 18 CONST_WIDE vAA, #+BBBBBBBBBBBBBBBB
buzbee67bf8852011-08-17 17:51:35 -0700105 DF_DA_WIDE | DF_SETS_CONST,
106
Elliott Hughesadb8c672012-03-06 16:49:32 -0800107 // 19 CONST_WIDE_HIGH16 vAA, #+BBBB000000000000
buzbee67bf8852011-08-17 17:51:35 -0700108 DF_DA_WIDE | DF_SETS_CONST,
109
Elliott Hughesadb8c672012-03-06 16:49:32 -0800110 // 1A CONST_STRING vAA, string@BBBB
buzbee67bc2362011-10-11 18:08:40 -0700111 DF_DA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700112
Elliott Hughesadb8c672012-03-06 16:49:32 -0800113 // 1B CONST_STRING_JUMBO vAA, string@BBBBBBBB
buzbee67bc2362011-10-11 18:08:40 -0700114 DF_DA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700115
Elliott Hughesadb8c672012-03-06 16:49:32 -0800116 // 1C CONST_CLASS vAA, type@BBBB
buzbee67bc2362011-10-11 18:08:40 -0700117 DF_DA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700118
Elliott Hughesadb8c672012-03-06 16:49:32 -0800119 // 1D MONITOR_ENTER vAA
buzbee67bc2362011-10-11 18:08:40 -0700120 DF_UA | DF_NULL_CHK_0 | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700121
Elliott Hughesadb8c672012-03-06 16:49:32 -0800122 // 1E MONITOR_EXIT vAA
buzbee67bc2362011-10-11 18:08:40 -0700123 DF_UA | DF_NULL_CHK_0 | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700124
Elliott Hughesadb8c672012-03-06 16:49:32 -0800125 // 1F CHK_CAST vAA, type@BBBB
buzbee9c044ce2012-03-18 13:24:07 -0700126 DF_UA | DF_CORE_A | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700127
Elliott Hughesadb8c672012-03-06 16:49:32 -0800128 // 20 INSTANCE_OF vA, vB, type@CCCC
buzbee9c044ce2012-03-18 13:24:07 -0700129 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700130
Elliott Hughesadb8c672012-03-06 16:49:32 -0800131 // 21 ARRAY_LENGTH vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700132 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700133
Elliott Hughesadb8c672012-03-06 16:49:32 -0800134 // 22 NEW_INSTANCE vAA, type@BBBB
buzbee9c044ce2012-03-18 13:24:07 -0700135 DF_DA | DF_NON_NULL_DST | DF_CORE_A | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700136
Elliott Hughesadb8c672012-03-06 16:49:32 -0800137 // 23 NEW_ARRAY vA, vB, type@CCCC
buzbee9c044ce2012-03-18 13:24:07 -0700138 DF_DA | DF_UB | DF_NON_NULL_DST | DF_CORE_A | DF_CORE_B | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700139
Elliott Hughesadb8c672012-03-06 16:49:32 -0800140 // 24 FILLED_NEW_ARRAY {vD, vE, vF, vG, vA}
buzbee9c044ce2012-03-18 13:24:07 -0700141 DF_FORMAT_35C | DF_NON_NULL_RET | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700142
Elliott Hughesadb8c672012-03-06 16:49:32 -0800143 // 25 FILLED_NEW_ARRAY_RANGE {vCCCC .. vNNNN}, type@BBBB
buzbee9c044ce2012-03-18 13:24:07 -0700144 DF_FORMAT_3RC | DF_NON_NULL_RET | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700145
Elliott Hughesadb8c672012-03-06 16:49:32 -0800146 // 26 FILL_ARRAY_DATA vAA, +BBBBBBBB
buzbee9c044ce2012-03-18 13:24:07 -0700147 DF_UA | DF_CORE_A | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700148
Elliott Hughesadb8c672012-03-06 16:49:32 -0800149 // 27 THROW vAA
buzbee9c044ce2012-03-18 13:24:07 -0700150 DF_UA | DF_CORE_A | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700151
Elliott Hughesadb8c672012-03-06 16:49:32 -0800152 // 28 GOTO
buzbee67bf8852011-08-17 17:51:35 -0700153 DF_NOP,
154
Elliott Hughesadb8c672012-03-06 16:49:32 -0800155 // 29 GOTO_16
buzbee67bf8852011-08-17 17:51:35 -0700156 DF_NOP,
157
Elliott Hughesadb8c672012-03-06 16:49:32 -0800158 // 2A GOTO_32
buzbee67bf8852011-08-17 17:51:35 -0700159 DF_NOP,
160
Elliott Hughesadb8c672012-03-06 16:49:32 -0800161 // 2B PACKED_SWITCH vAA, +BBBBBBBB
buzbee67bf8852011-08-17 17:51:35 -0700162 DF_UA,
163
Elliott Hughesadb8c672012-03-06 16:49:32 -0800164 // 2C SPARSE_SWITCH vAA, +BBBBBBBB
buzbee67bf8852011-08-17 17:51:35 -0700165 DF_UA,
166
Elliott Hughesadb8c672012-03-06 16:49:32 -0800167 // 2D CMPL_FLOAT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700168 DF_DA | DF_UB | DF_UC | DF_FP_B | DF_FP_C | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700169
Elliott Hughesadb8c672012-03-06 16:49:32 -0800170 // 2E CMPG_FLOAT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700171 DF_DA | DF_UB | DF_UC | DF_FP_B | DF_FP_C | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700172
Elliott Hughesadb8c672012-03-06 16:49:32 -0800173 // 2F CMPL_DOUBLE vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700174 DF_DA | DF_UB_WIDE | DF_UC_WIDE | DF_FP_B | DF_FP_C | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700175
Elliott Hughesadb8c672012-03-06 16:49:32 -0800176 // 30 CMPG_DOUBLE vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700177 DF_DA | DF_UB_WIDE | DF_UC_WIDE | DF_FP_B | DF_FP_C | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700178
Elliott Hughesadb8c672012-03-06 16:49:32 -0800179 // 31 CMP_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700180 DF_DA | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700181
Elliott Hughesadb8c672012-03-06 16:49:32 -0800182 // 32 IF_EQ vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700183 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700184
Elliott Hughesadb8c672012-03-06 16:49:32 -0800185 // 33 IF_NE vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700186 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700187
Elliott Hughesadb8c672012-03-06 16:49:32 -0800188 // 34 IF_LT vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700189 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700190
Elliott Hughesadb8c672012-03-06 16:49:32 -0800191 // 35 IF_GE vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700192 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700193
Elliott Hughesadb8c672012-03-06 16:49:32 -0800194 // 36 IF_GT vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700195 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700196
Elliott Hughesadb8c672012-03-06 16:49:32 -0800197 // 37 IF_LE vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700198 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700199
200
Elliott Hughesadb8c672012-03-06 16:49:32 -0800201 // 38 IF_EQZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700202 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700203
Elliott Hughesadb8c672012-03-06 16:49:32 -0800204 // 39 IF_NEZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700205 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700206
Elliott Hughesadb8c672012-03-06 16:49:32 -0800207 // 3A IF_LTZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700208 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700209
Elliott Hughesadb8c672012-03-06 16:49:32 -0800210 // 3B IF_GEZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700211 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700212
Elliott Hughesadb8c672012-03-06 16:49:32 -0800213 // 3C IF_GTZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700214 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700215
Elliott Hughesadb8c672012-03-06 16:49:32 -0800216 // 3D IF_LEZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700217 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700218
Elliott Hughesadb8c672012-03-06 16:49:32 -0800219 // 3E UNUSED_3E
buzbee67bf8852011-08-17 17:51:35 -0700220 DF_NOP,
221
Elliott Hughesadb8c672012-03-06 16:49:32 -0800222 // 3F UNUSED_3F
buzbee67bf8852011-08-17 17:51:35 -0700223 DF_NOP,
224
Elliott Hughesadb8c672012-03-06 16:49:32 -0800225 // 40 UNUSED_40
buzbee67bf8852011-08-17 17:51:35 -0700226 DF_NOP,
227
Elliott Hughesadb8c672012-03-06 16:49:32 -0800228 // 41 UNUSED_41
buzbee67bf8852011-08-17 17:51:35 -0700229 DF_NOP,
230
Elliott Hughesadb8c672012-03-06 16:49:32 -0800231 // 42 UNUSED_42
buzbee67bf8852011-08-17 17:51:35 -0700232 DF_NOP,
233
Elliott Hughesadb8c672012-03-06 16:49:32 -0800234 // 43 UNUSED_43
buzbee67bf8852011-08-17 17:51:35 -0700235 DF_NOP,
236
Elliott Hughesadb8c672012-03-06 16:49:32 -0800237 // 44 AGET vAA, vBB, vCC
buzbee9c044ce2012-03-18 13:24:07 -0700238 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700239
Elliott Hughesadb8c672012-03-06 16:49:32 -0800240 // 45 AGET_WIDE vAA, vBB, vCC
buzbee9c044ce2012-03-18 13:24:07 -0700241 DF_DA_WIDE | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700242
Elliott Hughesadb8c672012-03-06 16:49:32 -0800243 // 46 AGET_OBJECT vAA, vBB, vCC
buzbee9c044ce2012-03-18 13:24:07 -0700244 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700245
Elliott Hughesadb8c672012-03-06 16:49:32 -0800246 // 47 AGET_BOOLEAN vAA, vBB, vCC
buzbee9c044ce2012-03-18 13:24:07 -0700247 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700248
Elliott Hughesadb8c672012-03-06 16:49:32 -0800249 // 48 AGET_BYTE vAA, vBB, vCC
buzbee9c044ce2012-03-18 13:24:07 -0700250 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700251
Elliott Hughesadb8c672012-03-06 16:49:32 -0800252 // 49 AGET_CHAR vAA, vBB, vCC
buzbee9c044ce2012-03-18 13:24:07 -0700253 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700254
Elliott Hughesadb8c672012-03-06 16:49:32 -0800255 // 4A AGET_SHORT vAA, vBB, vCC
buzbee9c044ce2012-03-18 13:24:07 -0700256 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700257
Elliott Hughesadb8c672012-03-06 16:49:32 -0800258 // 4B APUT vAA, vBB, vCC
buzbee9c044ce2012-03-18 13:24:07 -0700259 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700260
Elliott Hughesadb8c672012-03-06 16:49:32 -0800261 // 4C APUT_WIDE vAA, vBB, vCC
buzbee9c044ce2012-03-18 13:24:07 -0700262 DF_UA_WIDE | DF_UB | DF_UC | DF_NULL_CHK_2 | DF_RANGE_CHK_3 | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700263
Elliott Hughesadb8c672012-03-06 16:49:32 -0800264 // 4D APUT_OBJECT vAA, vBB, vCC
buzbee9c044ce2012-03-18 13:24:07 -0700265 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700266
Elliott Hughesadb8c672012-03-06 16:49:32 -0800267 // 4E APUT_BOOLEAN vAA, vBB, vCC
buzbee9c044ce2012-03-18 13:24:07 -0700268 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700269
Elliott Hughesadb8c672012-03-06 16:49:32 -0800270 // 4F APUT_BYTE vAA, vBB, vCC
buzbee9c044ce2012-03-18 13:24:07 -0700271 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700272
Elliott Hughesadb8c672012-03-06 16:49:32 -0800273 // 50 APUT_CHAR vAA, vBB, vCC
buzbee9c044ce2012-03-18 13:24:07 -0700274 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700275
Elliott Hughesadb8c672012-03-06 16:49:32 -0800276 // 51 APUT_SHORT vAA, vBB, vCC
buzbee9c044ce2012-03-18 13:24:07 -0700277 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700278
Elliott Hughesadb8c672012-03-06 16:49:32 -0800279 // 52 IGET vA, vB, field@CCCC
buzbee9c044ce2012-03-18 13:24:07 -0700280 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700281
Elliott Hughesadb8c672012-03-06 16:49:32 -0800282 // 53 IGET_WIDE vA, vB, field@CCCC
buzbee9c044ce2012-03-18 13:24:07 -0700283 DF_DA_WIDE | DF_UB | DF_NULL_CHK_0 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700284
Elliott Hughesadb8c672012-03-06 16:49:32 -0800285 // 54 IGET_OBJECT vA, vB, field@CCCC
buzbee9c044ce2012-03-18 13:24:07 -0700286 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700287
Elliott Hughesadb8c672012-03-06 16:49:32 -0800288 // 55 IGET_BOOLEAN vA, vB, field@CCCC
buzbee9c044ce2012-03-18 13:24:07 -0700289 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700290
Elliott Hughesadb8c672012-03-06 16:49:32 -0800291 // 56 IGET_BYTE vA, vB, field@CCCC
buzbee9c044ce2012-03-18 13:24:07 -0700292 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700293
Elliott Hughesadb8c672012-03-06 16:49:32 -0800294 // 57 IGET_CHAR vA, vB, field@CCCC
buzbee9c044ce2012-03-18 13:24:07 -0700295 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700296
Elliott Hughesadb8c672012-03-06 16:49:32 -0800297 // 58 IGET_SHORT vA, vB, field@CCCC
buzbee9c044ce2012-03-18 13:24:07 -0700298 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700299
Elliott Hughesadb8c672012-03-06 16:49:32 -0800300 // 59 IPUT vA, vB, field@CCCC
buzbee9c044ce2012-03-18 13:24:07 -0700301 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700302
Elliott Hughesadb8c672012-03-06 16:49:32 -0800303 // 5A IPUT_WIDE vA, vB, field@CCCC
buzbee9c044ce2012-03-18 13:24:07 -0700304 DF_UA_WIDE | DF_UB | DF_NULL_CHK_2 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700305
Elliott Hughesadb8c672012-03-06 16:49:32 -0800306 // 5B IPUT_OBJECT vA, vB, field@CCCC
buzbee9c044ce2012-03-18 13:24:07 -0700307 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700308
Elliott Hughesadb8c672012-03-06 16:49:32 -0800309 // 5C IPUT_BOOLEAN vA, vB, field@CCCC
buzbee9c044ce2012-03-18 13:24:07 -0700310 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700311
Elliott Hughesadb8c672012-03-06 16:49:32 -0800312 // 5D IPUT_BYTE vA, vB, field@CCCC
buzbee9c044ce2012-03-18 13:24:07 -0700313 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700314
Elliott Hughesadb8c672012-03-06 16:49:32 -0800315 // 5E IPUT_CHAR vA, vB, field@CCCC
buzbee9c044ce2012-03-18 13:24:07 -0700316 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700317
Elliott Hughesadb8c672012-03-06 16:49:32 -0800318 // 5F IPUT_SHORT vA, vB, field@CCCC
buzbee9c044ce2012-03-18 13:24:07 -0700319 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700320
Elliott Hughesadb8c672012-03-06 16:49:32 -0800321 // 60 SGET vAA, field@BBBB
buzbee9c044ce2012-03-18 13:24:07 -0700322 DF_DA | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700323
Elliott Hughesadb8c672012-03-06 16:49:32 -0800324 // 61 SGET_WIDE vAA, field@BBBB
buzbee9c044ce2012-03-18 13:24:07 -0700325 DF_DA_WIDE | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700326
Elliott Hughesadb8c672012-03-06 16:49:32 -0800327 // 62 SGET_OBJECT vAA, field@BBBB
buzbee9c044ce2012-03-18 13:24:07 -0700328 DF_DA | DF_CORE_A | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700329
Elliott Hughesadb8c672012-03-06 16:49:32 -0800330 // 63 SGET_BOOLEAN vAA, field@BBBB
buzbee9c044ce2012-03-18 13:24:07 -0700331 DF_DA | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700332
Elliott Hughesadb8c672012-03-06 16:49:32 -0800333 // 64 SGET_BYTE vAA, field@BBBB
buzbee9c044ce2012-03-18 13:24:07 -0700334 DF_DA | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700335
Elliott Hughesadb8c672012-03-06 16:49:32 -0800336 // 65 SGET_CHAR vAA, field@BBBB
buzbee9c044ce2012-03-18 13:24:07 -0700337 DF_DA | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700338
Elliott Hughesadb8c672012-03-06 16:49:32 -0800339 // 66 SGET_SHORT vAA, field@BBBB
buzbee9c044ce2012-03-18 13:24:07 -0700340 DF_DA | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700341
Elliott Hughesadb8c672012-03-06 16:49:32 -0800342 // 67 SPUT vAA, field@BBBB
buzbee9c044ce2012-03-18 13:24:07 -0700343 DF_UA | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700344
Elliott Hughesadb8c672012-03-06 16:49:32 -0800345 // 68 SPUT_WIDE vAA, field@BBBB
buzbee9c044ce2012-03-18 13:24:07 -0700346 DF_UA_WIDE | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700347
Elliott Hughesadb8c672012-03-06 16:49:32 -0800348 // 69 SPUT_OBJECT vAA, field@BBBB
buzbee9c044ce2012-03-18 13:24:07 -0700349 DF_UA | DF_CORE_A | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700350
Elliott Hughesadb8c672012-03-06 16:49:32 -0800351 // 6A SPUT_BOOLEAN vAA, field@BBBB
buzbee9c044ce2012-03-18 13:24:07 -0700352 DF_UA | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700353
Elliott Hughesadb8c672012-03-06 16:49:32 -0800354 // 6B SPUT_BYTE vAA, field@BBBB
buzbee9c044ce2012-03-18 13:24:07 -0700355 DF_UA | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700356
Elliott Hughesadb8c672012-03-06 16:49:32 -0800357 // 6C SPUT_CHAR vAA, field@BBBB
buzbee9c044ce2012-03-18 13:24:07 -0700358 DF_UA | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700359
Elliott Hughesadb8c672012-03-06 16:49:32 -0800360 // 6D SPUT_SHORT vAA, field@BBBB
buzbee9c044ce2012-03-18 13:24:07 -0700361 DF_UA | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700362
Elliott Hughesadb8c672012-03-06 16:49:32 -0800363 // 6E INVOKE_VIRTUAL {vD, vE, vF, vG, vA}
buzbee9c044ce2012-03-18 13:24:07 -0700364 DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700365
Elliott Hughesadb8c672012-03-06 16:49:32 -0800366 // 6F INVOKE_SUPER {vD, vE, vF, vG, vA}
buzbee9c044ce2012-03-18 13:24:07 -0700367 DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700368
Elliott Hughesadb8c672012-03-06 16:49:32 -0800369 // 70 INVOKE_DIRECT {vD, vE, vF, vG, vA}
buzbee9c044ce2012-03-18 13:24:07 -0700370 DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700371
Elliott Hughesadb8c672012-03-06 16:49:32 -0800372 // 71 INVOKE_STATIC {vD, vE, vF, vG, vA}
buzbee9c044ce2012-03-18 13:24:07 -0700373 DF_FORMAT_35C | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700374
Elliott Hughesadb8c672012-03-06 16:49:32 -0800375 // 72 INVOKE_INTERFACE {vD, vE, vF, vG, vA}
buzbee9c044ce2012-03-18 13:24:07 -0700376 DF_FORMAT_35C | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700377
Elliott Hughesadb8c672012-03-06 16:49:32 -0800378 // 73 UNUSED_73
buzbee67bf8852011-08-17 17:51:35 -0700379 DF_NOP,
380
Elliott Hughesadb8c672012-03-06 16:49:32 -0800381 // 74 INVOKE_VIRTUAL_RANGE {vCCCC .. vNNNN}
buzbee9c044ce2012-03-18 13:24:07 -0700382 DF_FORMAT_3RC | DF_NULL_CHK_OUT0 | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700383
Elliott Hughesadb8c672012-03-06 16:49:32 -0800384 // 75 INVOKE_SUPER_RANGE {vCCCC .. vNNNN}
buzbee9c044ce2012-03-18 13:24:07 -0700385 DF_FORMAT_3RC | DF_NULL_CHK_OUT0 | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700386
Elliott Hughesadb8c672012-03-06 16:49:32 -0800387 // 76 INVOKE_DIRECT_RANGE {vCCCC .. vNNNN}
buzbee9c044ce2012-03-18 13:24:07 -0700388 DF_FORMAT_3RC | DF_NULL_CHK_OUT0 | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700389
Elliott Hughesadb8c672012-03-06 16:49:32 -0800390 // 77 INVOKE_STATIC_RANGE {vCCCC .. vNNNN}
buzbee9c044ce2012-03-18 13:24:07 -0700391 DF_FORMAT_3RC | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700392
Elliott Hughesadb8c672012-03-06 16:49:32 -0800393 // 78 INVOKE_INTERFACE_RANGE {vCCCC .. vNNNN}
buzbee9c044ce2012-03-18 13:24:07 -0700394 DF_FORMAT_3RC | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700395
Elliott Hughesadb8c672012-03-06 16:49:32 -0800396 // 79 UNUSED_79
buzbee67bf8852011-08-17 17:51:35 -0700397 DF_NOP,
398
Elliott Hughesadb8c672012-03-06 16:49:32 -0800399 // 7A UNUSED_7A
buzbee67bf8852011-08-17 17:51:35 -0700400 DF_NOP,
401
Elliott Hughesadb8c672012-03-06 16:49:32 -0800402 // 7B NEG_INT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700403 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700404
Elliott Hughesadb8c672012-03-06 16:49:32 -0800405 // 7C NOT_INT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700406 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700407
Elliott Hughesadb8c672012-03-06 16:49:32 -0800408 // 7D NEG_LONG vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700409 DF_DA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700410
Elliott Hughesadb8c672012-03-06 16:49:32 -0800411 // 7E NOT_LONG vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700412 DF_DA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700413
Elliott Hughesadb8c672012-03-06 16:49:32 -0800414 // 7F NEG_FLOAT vA, vB
buzbee67bf8852011-08-17 17:51:35 -0700415 DF_DA | DF_UB | DF_FP_A | DF_FP_B,
416
Elliott Hughesadb8c672012-03-06 16:49:32 -0800417 // 80 NEG_DOUBLE vA, vB
buzbee67bf8852011-08-17 17:51:35 -0700418 DF_DA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
419
Elliott Hughesadb8c672012-03-06 16:49:32 -0800420 // 81 INT_TO_LONG vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700421 DF_DA_WIDE | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700422
Elliott Hughesadb8c672012-03-06 16:49:32 -0800423 // 82 INT_TO_FLOAT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700424 DF_DA | DF_UB | DF_FP_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700425
Elliott Hughesadb8c672012-03-06 16:49:32 -0800426 // 83 INT_TO_DOUBLE vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700427 DF_DA_WIDE | DF_UB | DF_FP_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700428
Elliott Hughesadb8c672012-03-06 16:49:32 -0800429 // 84 LONG_TO_INT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700430 DF_DA | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700431
Elliott Hughesadb8c672012-03-06 16:49:32 -0800432 // 85 LONG_TO_FLOAT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700433 DF_DA | DF_UB_WIDE | DF_FP_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700434
Elliott Hughesadb8c672012-03-06 16:49:32 -0800435 // 86 LONG_TO_DOUBLE vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700436 DF_DA_WIDE | DF_UB_WIDE | DF_FP_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700437
Elliott Hughesadb8c672012-03-06 16:49:32 -0800438 // 87 FLOAT_TO_INT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700439 DF_DA | DF_UB | DF_FP_B | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700440
Elliott Hughesadb8c672012-03-06 16:49:32 -0800441 // 88 FLOAT_TO_LONG vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700442 DF_DA_WIDE | DF_UB | DF_FP_B | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700443
Elliott Hughesadb8c672012-03-06 16:49:32 -0800444 // 89 FLOAT_TO_DOUBLE vA, vB
buzbee67bf8852011-08-17 17:51:35 -0700445 DF_DA_WIDE | DF_UB | DF_FP_A | DF_FP_B,
446
Elliott Hughesadb8c672012-03-06 16:49:32 -0800447 // 8A DOUBLE_TO_INT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700448 DF_DA | DF_UB_WIDE | DF_FP_B | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700449
Elliott Hughesadb8c672012-03-06 16:49:32 -0800450 // 8B DOUBLE_TO_LONG vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700451 DF_DA_WIDE | DF_UB_WIDE | DF_FP_B | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700452
Elliott Hughesadb8c672012-03-06 16:49:32 -0800453 // 8C DOUBLE_TO_FLOAT vA, vB
buzbee67bf8852011-08-17 17:51:35 -0700454 DF_DA | DF_UB_WIDE | DF_FP_A | DF_FP_B,
455
Elliott Hughesadb8c672012-03-06 16:49:32 -0800456 // 8D INT_TO_BYTE vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700457 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700458
Elliott Hughesadb8c672012-03-06 16:49:32 -0800459 // 8E INT_TO_CHAR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700460 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700461
Elliott Hughesadb8c672012-03-06 16:49:32 -0800462 // 8F INT_TO_SHORT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700463 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700464
Elliott Hughesadb8c672012-03-06 16:49:32 -0800465 // 90 ADD_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700466 DF_DA | DF_UB | DF_UC | DF_IS_LINEAR | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700467
Elliott Hughesadb8c672012-03-06 16:49:32 -0800468 // 91 SUB_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700469 DF_DA | DF_UB | DF_UC | DF_IS_LINEAR | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700470
Elliott Hughesadb8c672012-03-06 16:49:32 -0800471 // 92 MUL_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700472 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700473
Elliott Hughesadb8c672012-03-06 16:49:32 -0800474 // 93 DIV_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700475 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700476
Elliott Hughesadb8c672012-03-06 16:49:32 -0800477 // 94 REM_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700478 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700479
Elliott Hughesadb8c672012-03-06 16:49:32 -0800480 // 95 AND_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700481 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700482
Elliott Hughesadb8c672012-03-06 16:49:32 -0800483 // 96 OR_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700484 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700485
Elliott Hughesadb8c672012-03-06 16:49:32 -0800486 // 97 XOR_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700487 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700488
Elliott Hughesadb8c672012-03-06 16:49:32 -0800489 // 98 SHL_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700490 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700491
Elliott Hughesadb8c672012-03-06 16:49:32 -0800492 // 99 SHR_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700493 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700494
Elliott Hughesadb8c672012-03-06 16:49:32 -0800495 // 9A USHR_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700496 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700497
Elliott Hughesadb8c672012-03-06 16:49:32 -0800498 // 9B ADD_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700499 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700500
Elliott Hughesadb8c672012-03-06 16:49:32 -0800501 // 9C SUB_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700502 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700503
Elliott Hughesadb8c672012-03-06 16:49:32 -0800504 // 9D MUL_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700505 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700506
Elliott Hughesadb8c672012-03-06 16:49:32 -0800507 // 9E DIV_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700508 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700509
Elliott Hughesadb8c672012-03-06 16:49:32 -0800510 // 9F REM_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700511 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700512
Elliott Hughesadb8c672012-03-06 16:49:32 -0800513 // A0 AND_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700514 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700515
Elliott Hughesadb8c672012-03-06 16:49:32 -0800516 // A1 OR_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700517 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700518
Elliott Hughesadb8c672012-03-06 16:49:32 -0800519 // A2 XOR_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700520 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700521
Elliott Hughesadb8c672012-03-06 16:49:32 -0800522 // A3 SHL_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700523 DF_DA_WIDE | DF_UB_WIDE | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700524
Elliott Hughesadb8c672012-03-06 16:49:32 -0800525 // A4 SHR_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700526 DF_DA_WIDE | DF_UB_WIDE | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700527
Elliott Hughesadb8c672012-03-06 16:49:32 -0800528 // A5 USHR_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700529 DF_DA_WIDE | DF_UB_WIDE | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700530
Elliott Hughesadb8c672012-03-06 16:49:32 -0800531 // A6 ADD_FLOAT vAA, vBB, vCC
buzbee67bf8852011-08-17 17:51:35 -0700532 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
533
Elliott Hughesadb8c672012-03-06 16:49:32 -0800534 // A7 SUB_FLOAT vAA, vBB, vCC
buzbee67bf8852011-08-17 17:51:35 -0700535 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
536
Elliott Hughesadb8c672012-03-06 16:49:32 -0800537 // A8 MUL_FLOAT vAA, vBB, vCC
buzbee67bf8852011-08-17 17:51:35 -0700538 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
539
Elliott Hughesadb8c672012-03-06 16:49:32 -0800540 // A9 DIV_FLOAT vAA, vBB, vCC
buzbee67bf8852011-08-17 17:51:35 -0700541 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
542
Elliott Hughesadb8c672012-03-06 16:49:32 -0800543 // AA REM_FLOAT vAA, vBB, vCC
buzbee67bf8852011-08-17 17:51:35 -0700544 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
545
Elliott Hughesadb8c672012-03-06 16:49:32 -0800546 // AB ADD_DOUBLE vAA, vBB, vCC
buzbee67bf8852011-08-17 17:51:35 -0700547 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
548
Elliott Hughesadb8c672012-03-06 16:49:32 -0800549 // AC SUB_DOUBLE vAA, vBB, vCC
buzbee67bf8852011-08-17 17:51:35 -0700550 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
551
Elliott Hughesadb8c672012-03-06 16:49:32 -0800552 // AD MUL_DOUBLE vAA, vBB, vCC
buzbee67bf8852011-08-17 17:51:35 -0700553 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
554
Elliott Hughesadb8c672012-03-06 16:49:32 -0800555 // AE DIV_DOUBLE vAA, vBB, vCC
buzbee67bf8852011-08-17 17:51:35 -0700556 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
557
Elliott Hughesadb8c672012-03-06 16:49:32 -0800558 // AF REM_DOUBLE vAA, vBB, vCC
buzbee67bf8852011-08-17 17:51:35 -0700559 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
560
Elliott Hughesadb8c672012-03-06 16:49:32 -0800561 // B0 ADD_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700562 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700563
Elliott Hughesadb8c672012-03-06 16:49:32 -0800564 // B1 SUB_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700565 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700566
Elliott Hughesadb8c672012-03-06 16:49:32 -0800567 // B2 MUL_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700568 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700569
Elliott Hughesadb8c672012-03-06 16:49:32 -0800570 // B3 DIV_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700571 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700572
Elliott Hughesadb8c672012-03-06 16:49:32 -0800573 // B4 REM_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700574 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700575
Elliott Hughesadb8c672012-03-06 16:49:32 -0800576 // B5 AND_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700577 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700578
Elliott Hughesadb8c672012-03-06 16:49:32 -0800579 // B6 OR_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700580 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700581
Elliott Hughesadb8c672012-03-06 16:49:32 -0800582 // B7 XOR_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700583 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700584
Elliott Hughesadb8c672012-03-06 16:49:32 -0800585 // B8 SHL_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700586 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700587
Elliott Hughesadb8c672012-03-06 16:49:32 -0800588 // B9 SHR_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700589 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700590
Elliott Hughesadb8c672012-03-06 16:49:32 -0800591 // BA USHR_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700592 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700593
Elliott Hughesadb8c672012-03-06 16:49:32 -0800594 // BB ADD_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700595 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700596
Elliott Hughesadb8c672012-03-06 16:49:32 -0800597 // BC SUB_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700598 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700599
Elliott Hughesadb8c672012-03-06 16:49:32 -0800600 // BD MUL_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700601 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700602
Elliott Hughesadb8c672012-03-06 16:49:32 -0800603 // BE DIV_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700604 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700605
Elliott Hughesadb8c672012-03-06 16:49:32 -0800606 // BF REM_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700607 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700608
Elliott Hughesadb8c672012-03-06 16:49:32 -0800609 // C0 AND_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700610 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700611
Elliott Hughesadb8c672012-03-06 16:49:32 -0800612 // C1 OR_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700613 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700614
Elliott Hughesadb8c672012-03-06 16:49:32 -0800615 // C2 XOR_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700616 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700617
Elliott Hughesadb8c672012-03-06 16:49:32 -0800618 // C3 SHL_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700619 DF_DA_WIDE | DF_UA_WIDE | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700620
Elliott Hughesadb8c672012-03-06 16:49:32 -0800621 // C4 SHR_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700622 DF_DA_WIDE | DF_UA_WIDE | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700623
Elliott Hughesadb8c672012-03-06 16:49:32 -0800624 // C5 USHR_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700625 DF_DA_WIDE | DF_UA_WIDE | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700626
Elliott Hughesadb8c672012-03-06 16:49:32 -0800627 // C6 ADD_FLOAT_2ADDR vA, vB
buzbee67bf8852011-08-17 17:51:35 -0700628 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
629
Elliott Hughesadb8c672012-03-06 16:49:32 -0800630 // C7 SUB_FLOAT_2ADDR vA, vB
buzbee67bf8852011-08-17 17:51:35 -0700631 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
632
Elliott Hughesadb8c672012-03-06 16:49:32 -0800633 // C8 MUL_FLOAT_2ADDR vA, vB
buzbee67bf8852011-08-17 17:51:35 -0700634 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
635
Elliott Hughesadb8c672012-03-06 16:49:32 -0800636 // C9 DIV_FLOAT_2ADDR vA, vB
buzbee67bf8852011-08-17 17:51:35 -0700637 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
638
Elliott Hughesadb8c672012-03-06 16:49:32 -0800639 // CA REM_FLOAT_2ADDR vA, vB
buzbee67bf8852011-08-17 17:51:35 -0700640 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
641
Elliott Hughesadb8c672012-03-06 16:49:32 -0800642 // CB ADD_DOUBLE_2ADDR vA, vB
buzbee67bf8852011-08-17 17:51:35 -0700643 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
644
Elliott Hughesadb8c672012-03-06 16:49:32 -0800645 // CC SUB_DOUBLE_2ADDR vA, vB
buzbee67bf8852011-08-17 17:51:35 -0700646 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
647
Elliott Hughesadb8c672012-03-06 16:49:32 -0800648 // CD MUL_DOUBLE_2ADDR vA, vB
buzbee67bf8852011-08-17 17:51:35 -0700649 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
650
Elliott Hughesadb8c672012-03-06 16:49:32 -0800651 // CE DIV_DOUBLE_2ADDR vA, vB
buzbee67bf8852011-08-17 17:51:35 -0700652 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
653
Elliott Hughesadb8c672012-03-06 16:49:32 -0800654 // CF REM_DOUBLE_2ADDR vA, vB
buzbee67bf8852011-08-17 17:51:35 -0700655 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
656
Elliott Hughesadb8c672012-03-06 16:49:32 -0800657 // D0 ADD_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700658 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700659
Elliott Hughesadb8c672012-03-06 16:49:32 -0800660 // D1 RSUB_INT vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700661 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700662
Elliott Hughesadb8c672012-03-06 16:49:32 -0800663 // D2 MUL_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700664 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700665
Elliott Hughesadb8c672012-03-06 16:49:32 -0800666 // D3 DIV_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700667 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700668
Elliott Hughesadb8c672012-03-06 16:49:32 -0800669 // D4 REM_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700670 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700671
Elliott Hughesadb8c672012-03-06 16:49:32 -0800672 // D5 AND_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700673 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700674
Elliott Hughesadb8c672012-03-06 16:49:32 -0800675 // D6 OR_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700676 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700677
Elliott Hughesadb8c672012-03-06 16:49:32 -0800678 // D7 XOR_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700679 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700680
Elliott Hughesadb8c672012-03-06 16:49:32 -0800681 // D8 ADD_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700682 DF_DA | DF_UB | DF_IS_LINEAR | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700683
Elliott Hughesadb8c672012-03-06 16:49:32 -0800684 // D9 RSUB_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700685 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700686
Elliott Hughesadb8c672012-03-06 16:49:32 -0800687 // DA MUL_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700688 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700689
Elliott Hughesadb8c672012-03-06 16:49:32 -0800690 // DB DIV_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700691 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700692
Elliott Hughesadb8c672012-03-06 16:49:32 -0800693 // DC REM_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700694 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700695
Elliott Hughesadb8c672012-03-06 16:49:32 -0800696 // DD AND_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700697 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700698
Elliott Hughesadb8c672012-03-06 16:49:32 -0800699 // DE OR_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700700 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700701
Elliott Hughesadb8c672012-03-06 16:49:32 -0800702 // DF XOR_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700703 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700704
Elliott Hughesadb8c672012-03-06 16:49:32 -0800705 // E0 SHL_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700706 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700707
Elliott Hughesadb8c672012-03-06 16:49:32 -0800708 // E1 SHR_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700709 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700710
Elliott Hughesadb8c672012-03-06 16:49:32 -0800711 // E2 USHR_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700712 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700713
Elliott Hughesadb8c672012-03-06 16:49:32 -0800714 // E3 IGET_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700715 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700716
Elliott Hughesadb8c672012-03-06 16:49:32 -0800717 // E4 IPUT_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700718 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700719
Elliott Hughesadb8c672012-03-06 16:49:32 -0800720 // E5 SGET_VOLATILE
buzbee9c044ce2012-03-18 13:24:07 -0700721 DF_DA | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700722
Elliott Hughesadb8c672012-03-06 16:49:32 -0800723 // E6 SPUT_VOLATILE
buzbee9c044ce2012-03-18 13:24:07 -0700724 DF_UA | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700725
Elliott Hughesadb8c672012-03-06 16:49:32 -0800726 // E7 IGET_OBJECT_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700727 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700728
Elliott Hughesadb8c672012-03-06 16:49:32 -0800729 // E8 IGET_WIDE_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700730 DF_DA_WIDE | DF_UB | DF_NULL_CHK_0 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700731
Elliott Hughesadb8c672012-03-06 16:49:32 -0800732 // E9 IPUT_WIDE_VOLATILE
buzbee239c4e72012-03-16 08:42:29 -0700733 DF_UA_WIDE | DF_UB | DF_NULL_CHK_2 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700734
Elliott Hughesadb8c672012-03-06 16:49:32 -0800735 // EA SGET_WIDE_VOLATILE
buzbee9c044ce2012-03-18 13:24:07 -0700736 DF_DA_WIDE | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700737
Elliott Hughesadb8c672012-03-06 16:49:32 -0800738 // EB SPUT_WIDE_VOLATILE
buzbee9c044ce2012-03-18 13:24:07 -0700739 DF_UA_WIDE | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700740
Elliott Hughesadb8c672012-03-06 16:49:32 -0800741 // EC BREAKPOINT
buzbee67bf8852011-08-17 17:51:35 -0700742 DF_NOP,
743
Elliott Hughesadb8c672012-03-06 16:49:32 -0800744 // ED THROW_VERIFICATION_ERROR
buzbee9c044ce2012-03-18 13:24:07 -0700745 DF_NOP | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700746
Elliott Hughesadb8c672012-03-06 16:49:32 -0800747 // EE EXECUTE_INLINE
buzbee67bf8852011-08-17 17:51:35 -0700748 DF_FORMAT_35C,
749
Elliott Hughesadb8c672012-03-06 16:49:32 -0800750 // EF EXECUTE_INLINE_RANGE
buzbee67bf8852011-08-17 17:51:35 -0700751 DF_FORMAT_3RC,
752
Elliott Hughesadb8c672012-03-06 16:49:32 -0800753 // F0 INVOKE_OBJECT_INIT_RANGE
buzbee43a36422011-09-14 14:00:13 -0700754 DF_NOP | DF_NULL_CHK_0,
buzbee67bf8852011-08-17 17:51:35 -0700755
Elliott Hughesadb8c672012-03-06 16:49:32 -0800756 // F1 RETURN_VOID_BARRIER
buzbee67bf8852011-08-17 17:51:35 -0700757 DF_NOP,
758
Elliott Hughesadb8c672012-03-06 16:49:32 -0800759 // F2 IGET_QUICK
buzbee9c044ce2012-03-18 13:24:07 -0700760 DF_DA | DF_UB | DF_NULL_CHK_0,
buzbee67bf8852011-08-17 17:51:35 -0700761
Elliott Hughesadb8c672012-03-06 16:49:32 -0800762 // F3 IGET_WIDE_QUICK
buzbee9c044ce2012-03-18 13:24:07 -0700763 DF_DA_WIDE | DF_UB | DF_NULL_CHK_0,
buzbee67bf8852011-08-17 17:51:35 -0700764
Elliott Hughesadb8c672012-03-06 16:49:32 -0800765 // F4 IGET_OBJECT_QUICK
buzbee9c044ce2012-03-18 13:24:07 -0700766 DF_DA | DF_UB | DF_NULL_CHK_0,
buzbee67bf8852011-08-17 17:51:35 -0700767
Elliott Hughesadb8c672012-03-06 16:49:32 -0800768 // F5 IPUT_QUICK
buzbee9c044ce2012-03-18 13:24:07 -0700769 DF_UA | DF_UB | DF_NULL_CHK_1,
buzbee67bf8852011-08-17 17:51:35 -0700770
Elliott Hughesadb8c672012-03-06 16:49:32 -0800771 // F6 IPUT_WIDE_QUICK
buzbee9c044ce2012-03-18 13:24:07 -0700772 DF_UA_WIDE | DF_UB | DF_NULL_CHK_2,
buzbee67bf8852011-08-17 17:51:35 -0700773
Elliott Hughesadb8c672012-03-06 16:49:32 -0800774 // F7 IPUT_OBJECT_QUICK
buzbee9c044ce2012-03-18 13:24:07 -0700775 DF_UA | DF_UB | DF_NULL_CHK_1,
buzbee67bf8852011-08-17 17:51:35 -0700776
Elliott Hughesadb8c672012-03-06 16:49:32 -0800777 // F8 INVOKE_VIRTUAL_QUICK
buzbee9c044ce2012-03-18 13:24:07 -0700778 DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700779
Elliott Hughesadb8c672012-03-06 16:49:32 -0800780 // F9 INVOKE_VIRTUAL_QUICK_RANGE
buzbee9c044ce2012-03-18 13:24:07 -0700781 DF_FORMAT_3RC | DF_NULL_CHK_OUT0 | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700782
Elliott Hughesadb8c672012-03-06 16:49:32 -0800783 // FA INVOKE_SUPER_QUICK
buzbee9c044ce2012-03-18 13:24:07 -0700784 DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700785
Elliott Hughesadb8c672012-03-06 16:49:32 -0800786 // FB INVOKE_SUPER_QUICK_RANGE
buzbee9c044ce2012-03-18 13:24:07 -0700787 DF_FORMAT_3RC | DF_NULL_CHK_OUT0 | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700788
Elliott Hughesadb8c672012-03-06 16:49:32 -0800789 // FC IPUT_OBJECT_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700790 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700791
Elliott Hughesadb8c672012-03-06 16:49:32 -0800792 // FD SGET_OBJECT_VOLATILE
buzbee9c044ce2012-03-18 13:24:07 -0700793 DF_DA | DF_CORE_A | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700794
Elliott Hughesadb8c672012-03-06 16:49:32 -0800795 // FE SPUT_OBJECT_VOLATILE
buzbee9c044ce2012-03-18 13:24:07 -0700796 DF_UA | DF_CORE_A | DF_UMS,
buzbee67bf8852011-08-17 17:51:35 -0700797
Elliott Hughesadb8c672012-03-06 16:49:32 -0800798 // FF UNUSED_FF
buzbee67bf8852011-08-17 17:51:35 -0700799 DF_NOP,
800
801 // Beginning of extended MIR opcodes
Elliott Hughesadb8c672012-03-06 16:49:32 -0800802 // 100 MIR_PHI
buzbee43a36422011-09-14 14:00:13 -0700803 DF_PHI | DF_DA | DF_NULL_TRANSFER_N,
buzbee67bf8852011-08-17 17:51:35 -0700804 /*
805 * For extended MIR inserted at the MIR2LIR stage, it is okay to have
806 * undefined values here.
807 */
808};
809
buzbeee1965672012-03-11 18:39:19 -0700810/* Return the base virtual register for a SSA name */
811int SRegToVReg(const CompilationUnit* cUnit, int ssaReg)
buzbee67bf8852011-08-17 17:51:35 -0700812{
buzbeee1965672012-03-11 18:39:19 -0700813 DCHECK_LT(ssaReg, (int)cUnit->ssaBaseVRegs->numUsed);
814 return GET_ELEM_N(cUnit->ssaBaseVRegs, int, ssaReg);
buzbee67bf8852011-08-17 17:51:35 -0700815}
816
buzbeee1965672012-03-11 18:39:19 -0700817int SRegToSubscript(const CompilationUnit* cUnit, int ssaReg)
818{
819 DCHECK(ssaReg < (int)cUnit->ssaSubscripts->numUsed);
820 return GET_ELEM_N(cUnit->ssaSubscripts, int, ssaReg);
821}
822
buzbeeba938cb2012-02-03 14:47:55 -0800823char* oatGetDalvikDisassembly(CompilationUnit* cUnit,
Elliott Hughesadb8c672012-03-06 16:49:32 -0800824 const DecodedInstruction& insn, const char* note)
buzbee67bf8852011-08-17 17:51:35 -0700825{
826 char buffer[256];
Elliott Hughesadb8c672012-03-06 16:49:32 -0800827 Instruction::Code opcode = insn.opcode;
buzbee67bf8852011-08-17 17:51:35 -0700828 int dfAttributes = oatDataFlowAttributes[opcode];
829 int flags;
830 char* ret;
831
832 buffer[0] = 0;
833 if ((int)opcode >= (int)kMirOpFirst) {
834 if ((int)opcode == (int)kMirOpPhi) {
835 strcpy(buffer, "PHI");
Elliott Hughesadb8c672012-03-06 16:49:32 -0800836 } else {
buzbee67bf8852011-08-17 17:51:35 -0700837 sprintf(buffer, "Opcode %#x", opcode);
838 }
839 flags = 0;
840 } else {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800841 strcpy(buffer, Instruction::Name(opcode));
842 flags = Instruction::Flags(opcode);
buzbee67bf8852011-08-17 17:51:35 -0700843 }
844
845 if (note)
846 strcat(buffer, note);
847
848 /* For branches, decode the instructions to print out the branch targets */
Elliott Hughesadb8c672012-03-06 16:49:32 -0800849 if (flags & Instruction::kBranch) {
850 Instruction::Format dalvikFormat = Instruction::FormatOf(insn.opcode);
buzbee67bf8852011-08-17 17:51:35 -0700851 int offset = 0;
852 switch (dalvikFormat) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800853 case Instruction::k21t:
854 snprintf(buffer + strlen(buffer), 256, " v%d,", insn.vA);
855 offset = (int) insn.vB;
buzbee67bf8852011-08-17 17:51:35 -0700856 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800857 case Instruction::k22t:
858 snprintf(buffer + strlen(buffer), 256, " v%d, v%d,", insn.vA, insn.vB);
859 offset = (int) insn.vC;
buzbee67bf8852011-08-17 17:51:35 -0700860 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800861 case Instruction::k10t:
862 case Instruction::k20t:
863 case Instruction::k30t:
864 offset = (int) insn.vA;
buzbee67bf8852011-08-17 17:51:35 -0700865 break;
866 default:
867 LOG(FATAL) << "Unexpected branch format " << (int)dalvikFormat
868 << " / opcode " << (int)opcode;
869 }
870 snprintf(buffer + strlen(buffer), 256, " (%c%x)",
871 offset > 0 ? '+' : '-',
872 offset > 0 ? offset : -offset);
873 } else if (dfAttributes & DF_FORMAT_35C) {
874 unsigned int i;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800875 for (i = 0; i < insn.vA; i++) {
buzbee67bf8852011-08-17 17:51:35 -0700876 if (i != 0) strcat(buffer, ",");
Elliott Hughesadb8c672012-03-06 16:49:32 -0800877 snprintf(buffer + strlen(buffer), 256, " v%d", insn.arg[i]);
buzbee67bf8852011-08-17 17:51:35 -0700878 }
879 }
880 else if (dfAttributes & DF_FORMAT_3RC) {
881 snprintf(buffer + strlen(buffer), 256,
Elliott Hughesadb8c672012-03-06 16:49:32 -0800882 " v%d..v%d", insn.vC, insn.vC + insn.vA - 1);
buzbee67bf8852011-08-17 17:51:35 -0700883 }
884 else {
885 if (dfAttributes & DF_A_IS_REG) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800886 snprintf(buffer + strlen(buffer), 256, " v%d", insn.vA);
buzbee67bf8852011-08-17 17:51:35 -0700887 }
888 if (dfAttributes & DF_B_IS_REG) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800889 snprintf(buffer + strlen(buffer), 256, ", v%d", insn.vB);
buzbee67bf8852011-08-17 17:51:35 -0700890 }
891 else if ((int)opcode < (int)kMirOpFirst) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800892 snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn.vB);
buzbee67bf8852011-08-17 17:51:35 -0700893 }
894 if (dfAttributes & DF_C_IS_REG) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800895 snprintf(buffer + strlen(buffer), 256, ", v%d", insn.vC);
buzbee67bf8852011-08-17 17:51:35 -0700896 }
897 else if ((int)opcode < (int)kMirOpFirst) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800898 snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn.vC);
buzbee67bf8852011-08-17 17:51:35 -0700899 }
900 }
901 int length = strlen(buffer) + 1;
buzbeeba938cb2012-02-03 14:47:55 -0800902 ret = (char*)oatNew(cUnit, length, false, kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -0700903 memcpy(ret, buffer, length);
904 return ret;
905}
906
Elliott Hughesc1f143d2011-12-01 17:31:10 -0800907char* getSSAName(const CompilationUnit* cUnit, int ssaReg, char* name)
buzbee67bf8852011-08-17 17:51:35 -0700908{
buzbeee1965672012-03-11 18:39:19 -0700909 sprintf(name, "v%d_%d", SRegToVReg(cUnit, ssaReg),
910 SRegToSubscript(cUnit, ssaReg));
buzbee67bf8852011-08-17 17:51:35 -0700911 return name;
912}
913
914/*
915 * Dalvik instruction disassembler with optional SSA printing.
916 */
buzbee31a4a6f2012-02-28 15:36:15 -0800917char* oatFullDisassembler(CompilationUnit* cUnit, const MIR* mir)
buzbee67bf8852011-08-17 17:51:35 -0700918{
919 char buffer[256];
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700920 char operand0[32], operand1[32];
Elliott Hughesadb8c672012-03-06 16:49:32 -0800921 const DecodedInstruction* insn = &mir->dalvikInsn;
922 Instruction::Code opcode = insn->opcode;
buzbee67bf8852011-08-17 17:51:35 -0700923 int dfAttributes = oatDataFlowAttributes[opcode];
Elliott Hughesc1f143d2011-12-01 17:31:10 -0800924 char* ret;
buzbee67bf8852011-08-17 17:51:35 -0700925 int length;
buzbee67bf8852011-08-17 17:51:35 -0700926
927 buffer[0] = 0;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800928 if (static_cast<int>(opcode) >= static_cast<int>(kMirOpFirst)) {
929 if (static_cast<int>(opcode) == static_cast<int>(kMirOpPhi)) {
buzbee67bf8852011-08-17 17:51:35 -0700930 snprintf(buffer, 256, "PHI %s = (%s",
931 getSSAName(cUnit, mir->ssaRep->defs[0], operand0),
932 getSSAName(cUnit, mir->ssaRep->uses[0], operand1));
933 int i;
934 for (i = 1; i < mir->ssaRep->numUses; i++) {
935 snprintf(buffer + strlen(buffer), 256, ", %s",
936 getSSAName(cUnit, mir->ssaRep->uses[i], operand0));
937 }
938 snprintf(buffer + strlen(buffer), 256, ")");
939 }
940 else {
941 sprintf(buffer, "Opcode %#x", opcode);
942 }
943 goto done;
944 } else {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800945 strcpy(buffer, Instruction::Name(opcode));
buzbee67bf8852011-08-17 17:51:35 -0700946 }
947
buzbee67bf8852011-08-17 17:51:35 -0700948 /* For branches, decode the instructions to print out the branch targets */
Elliott Hughesadb8c672012-03-06 16:49:32 -0800949 if (Instruction::Flags(insn->opcode) & Instruction::kBranch) {
950 Instruction::Format dalvikFormat = Instruction::FormatOf(insn->opcode);
buzbee67bf8852011-08-17 17:51:35 -0700951 int delta = 0;
952 switch (dalvikFormat) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800953 case Instruction::k21t:
buzbee67bf8852011-08-17 17:51:35 -0700954 snprintf(buffer + strlen(buffer), 256, " %s, ",
955 getSSAName(cUnit, mir->ssaRep->uses[0], operand0));
956 delta = (int) insn->vB;
957 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800958 case Instruction::k22t:
buzbee67bf8852011-08-17 17:51:35 -0700959 snprintf(buffer + strlen(buffer), 256, " %s, %s, ",
960 getSSAName(cUnit, mir->ssaRep->uses[0], operand0),
961 getSSAName(cUnit, mir->ssaRep->uses[1], operand1));
962 delta = (int) insn->vC;
963 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800964 case Instruction::k10t:
965 case Instruction::k20t:
966 case Instruction::k30t:
buzbee67bf8852011-08-17 17:51:35 -0700967 delta = (int) insn->vA;
968 break;
969 default:
970 LOG(FATAL) << "Unexpected branch format: " <<
971 (int)dalvikFormat;
972 }
973 snprintf(buffer + strlen(buffer), 256, " %04x",
974 mir->offset + delta);
975 } else if (dfAttributes & (DF_FORMAT_35C | DF_FORMAT_3RC)) {
976 unsigned int i;
977 for (i = 0; i < insn->vA; i++) {
978 if (i != 0) strcat(buffer, ",");
979 snprintf(buffer + strlen(buffer), 256, " %s",
980 getSSAName(cUnit, mir->ssaRep->uses[i], operand0));
981 }
982 } else {
983 int udIdx;
984 if (mir->ssaRep->numDefs) {
985
986 for (udIdx = 0; udIdx < mir->ssaRep->numDefs; udIdx++) {
987 snprintf(buffer + strlen(buffer), 256, " %s",
988 getSSAName(cUnit, mir->ssaRep->defs[udIdx], operand0));
989 }
990 strcat(buffer, ",");
991 }
992 if (mir->ssaRep->numUses) {
993 /* No leading ',' for the first use */
994 snprintf(buffer + strlen(buffer), 256, " %s",
995 getSSAName(cUnit, mir->ssaRep->uses[0], operand0));
996 for (udIdx = 1; udIdx < mir->ssaRep->numUses; udIdx++) {
997 snprintf(buffer + strlen(buffer), 256, ", %s",
998 getSSAName(cUnit, mir->ssaRep->uses[udIdx], operand0));
999 }
1000 }
Elliott Hughesadb8c672012-03-06 16:49:32 -08001001 if (static_cast<int>(opcode) < static_cast<int>(kMirOpFirst)) {
1002 Instruction::Format dalvikFormat = Instruction::FormatOf(opcode);
buzbee67bf8852011-08-17 17:51:35 -07001003 switch (dalvikFormat) {
Elliott Hughesadb8c672012-03-06 16:49:32 -08001004 case Instruction::k11n: // op vA, #+B
1005 case Instruction::k21s: // op vAA, #+BBBB
1006 case Instruction::k21h: // op vAA, #+BBBB00000[00000000]
1007 case Instruction::k31i: // op vAA, #+BBBBBBBB
1008 case Instruction::k51l: // op vAA, #+BBBBBBBBBBBBBBBB
buzbee67bf8852011-08-17 17:51:35 -07001009 snprintf(buffer + strlen(buffer), 256, " #%#x", insn->vB);
1010 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -08001011 case Instruction::k21c: // op vAA, thing@BBBB
1012 case Instruction::k31c: // op vAA, thing@BBBBBBBB
buzbee67bf8852011-08-17 17:51:35 -07001013 snprintf(buffer + strlen(buffer), 256, " @%#x", insn->vB);
1014 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -08001015 case Instruction::k22b: // op vAA, vBB, #+CC
1016 case Instruction::k22s: // op vA, vB, #+CCCC
buzbee67bf8852011-08-17 17:51:35 -07001017 snprintf(buffer + strlen(buffer), 256, " #%#x", insn->vC);
1018 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -08001019 case Instruction::k22c: // op vA, vB, thing@CCCC
buzbee67bf8852011-08-17 17:51:35 -07001020 snprintf(buffer + strlen(buffer), 256, " @%#x", insn->vC);
1021 break;
1022 /* No need for special printing */
1023 default:
1024 break;
1025 }
1026 }
1027 }
1028
1029done:
1030 length = strlen(buffer) + 1;
buzbeeba938cb2012-02-03 14:47:55 -08001031 ret = (char*) oatNew(cUnit, length, false, kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001032 memcpy(ret, buffer, length);
1033 return ret;
1034}
1035
Elliott Hughesc1f143d2011-12-01 17:31:10 -08001036char* oatGetSSAString(CompilationUnit* cUnit, SSARepresentation* ssaRep)
buzbee67bf8852011-08-17 17:51:35 -07001037{
1038 char buffer[256];
1039 char* ret;
1040 int i;
1041
1042 buffer[0] = 0;
1043 for (i = 0; i < ssaRep->numDefs; i++) {
buzbeee1965672012-03-11 18:39:19 -07001044 int ssaReg = ssaRep->defs[i];
1045 sprintf(buffer + strlen(buffer), "s%d(v%d_%d) ", ssaReg,
1046 SRegToVReg(cUnit, ssaReg), SRegToSubscript(cUnit, ssaReg));
buzbee67bf8852011-08-17 17:51:35 -07001047 }
1048
1049 if (ssaRep->numDefs) {
1050 strcat(buffer, "<- ");
1051 }
1052
1053 for (i = 0; i < ssaRep->numUses; i++) {
buzbee67bf8852011-08-17 17:51:35 -07001054 int len = strlen(buffer);
buzbeee1965672012-03-11 18:39:19 -07001055 int ssaReg = ssaRep->uses[i];
buzbee67bf8852011-08-17 17:51:35 -07001056
buzbeee1965672012-03-11 18:39:19 -07001057 if (snprintf(buffer + len, 250 - len, "s%d(v%d_%d) ", ssaReg,
1058 SRegToVReg(cUnit, ssaReg),
1059 SRegToSubscript(cUnit, ssaReg))) {
buzbee67bf8852011-08-17 17:51:35 -07001060 strcat(buffer, "...");
1061 break;
1062 }
1063 }
1064
1065 int length = strlen(buffer) + 1;
buzbeeba938cb2012-02-03 14:47:55 -08001066 ret = (char*)oatNew(cUnit, length, false, kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001067 memcpy(ret, buffer, length);
1068 return ret;
1069}
1070
1071/* Any register that is used before being defined is considered live-in */
buzbee31a4a6f2012-02-28 15:36:15 -08001072inline void handleLiveInUse(CompilationUnit* cUnit, ArenaBitVector* useV,
1073 ArenaBitVector* defV, ArenaBitVector* liveInV,
1074 int dalvikRegId)
buzbee67bf8852011-08-17 17:51:35 -07001075{
buzbeeba938cb2012-02-03 14:47:55 -08001076 oatSetBit(cUnit, useV, dalvikRegId);
buzbee67bf8852011-08-17 17:51:35 -07001077 if (!oatIsBitSet(defV, dalvikRegId)) {
buzbeeba938cb2012-02-03 14:47:55 -08001078 oatSetBit(cUnit, liveInV, dalvikRegId);
buzbee67bf8852011-08-17 17:51:35 -07001079 }
1080}
1081
1082/* Mark a reg as being defined */
buzbee31a4a6f2012-02-28 15:36:15 -08001083inline void handleDef(CompilationUnit* cUnit, ArenaBitVector* defV,
1084 int dalvikRegId)
buzbee67bf8852011-08-17 17:51:35 -07001085{
buzbeeba938cb2012-02-03 14:47:55 -08001086 oatSetBit(cUnit, defV, dalvikRegId);
buzbee67bf8852011-08-17 17:51:35 -07001087}
1088
1089/*
1090 * Find out live-in variables for natural loops. Variables that are live-in in
1091 * the main loop body are considered to be defined in the entry block.
1092 */
1093bool oatFindLocalLiveIn(CompilationUnit* cUnit, BasicBlock* bb)
1094{
1095 MIR* mir;
1096 ArenaBitVector *useV, *defV, *liveInV;
1097
1098 if (bb->dataFlowInfo == NULL) return false;
1099
1100 useV = bb->dataFlowInfo->useV =
buzbeeba938cb2012-02-03 14:47:55 -08001101 oatAllocBitVector(cUnit, cUnit->numDalvikRegisters, false, kBitMapUse);
buzbee67bf8852011-08-17 17:51:35 -07001102 defV = bb->dataFlowInfo->defV =
buzbeeba938cb2012-02-03 14:47:55 -08001103 oatAllocBitVector(cUnit, cUnit->numDalvikRegisters, false, kBitMapDef);
buzbee67bf8852011-08-17 17:51:35 -07001104 liveInV = bb->dataFlowInfo->liveInV =
buzbeeba938cb2012-02-03 14:47:55 -08001105 oatAllocBitVector(cUnit, cUnit->numDalvikRegisters, false,
1106 kBitMapLiveIn);
buzbee67bf8852011-08-17 17:51:35 -07001107
1108 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1109 int dfAttributes =
1110 oatDataFlowAttributes[mir->dalvikInsn.opcode];
1111 DecodedInstruction *dInsn = &mir->dalvikInsn;
1112
1113 if (dfAttributes & DF_HAS_USES) {
1114 if (dfAttributes & DF_UA) {
buzbeeba938cb2012-02-03 14:47:55 -08001115 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vA);
buzbee67bf8852011-08-17 17:51:35 -07001116 } else if (dfAttributes & DF_UA_WIDE) {
buzbeeba938cb2012-02-03 14:47:55 -08001117 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vA);
1118 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vA+1);
buzbee67bf8852011-08-17 17:51:35 -07001119 }
1120 if (dfAttributes & DF_UB) {
buzbeeba938cb2012-02-03 14:47:55 -08001121 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vB);
buzbee67bf8852011-08-17 17:51:35 -07001122 } else if (dfAttributes & DF_UB_WIDE) {
buzbeeba938cb2012-02-03 14:47:55 -08001123 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vB);
1124 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vB+1);
buzbee67bf8852011-08-17 17:51:35 -07001125 }
1126 if (dfAttributes & DF_UC) {
buzbeeba938cb2012-02-03 14:47:55 -08001127 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vC);
buzbee67bf8852011-08-17 17:51:35 -07001128 } else if (dfAttributes & DF_UC_WIDE) {
buzbeeba938cb2012-02-03 14:47:55 -08001129 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vC);
1130 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vC+1);
buzbee67bf8852011-08-17 17:51:35 -07001131 }
1132 }
buzbee07ce1d72012-02-10 17:22:02 -08001133 if (dfAttributes & DF_FORMAT_35C) {
1134 for (unsigned int i = 0; i < dInsn->vA; i++) {
1135 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->arg[i]);
1136 }
1137 }
1138 if (dfAttributes & DF_FORMAT_3RC) {
1139 for (unsigned int i = 0; i < dInsn->vA; i++) {
1140 handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vC+i);
1141 }
1142 }
buzbee67bf8852011-08-17 17:51:35 -07001143 if (dfAttributes & DF_HAS_DEFS) {
buzbeeba938cb2012-02-03 14:47:55 -08001144 handleDef(cUnit, defV, dInsn->vA);
buzbee67bf8852011-08-17 17:51:35 -07001145 if (dfAttributes & DF_DA_WIDE) {
buzbeeba938cb2012-02-03 14:47:55 -08001146 handleDef(cUnit, defV, dInsn->vA+1);
buzbee67bf8852011-08-17 17:51:35 -07001147 }
1148 }
1149 }
1150 return true;
1151}
1152
buzbeee1965672012-03-11 18:39:19 -07001153int addNewSReg(CompilationUnit* cUnit, int vReg)
1154{
1155 // Compiler temps always have a subscript of 0
1156 int subscript = (vReg < 0) ? 0 : ++cUnit->SSALastDefs[vReg];
1157 int ssaReg = cUnit->numSSARegs++;
1158 oatInsertGrowableList(cUnit, cUnit->ssaBaseVRegs, vReg);
1159 oatInsertGrowableList(cUnit, cUnit->ssaSubscripts, subscript);
1160 DCHECK_EQ(cUnit->ssaBaseVRegs->numUsed, cUnit->ssaSubscripts->numUsed);
1161 return ssaReg;
1162}
1163
buzbee67bf8852011-08-17 17:51:35 -07001164/* Find out the latest SSA register for a given Dalvik register */
buzbee31a4a6f2012-02-28 15:36:15 -08001165void handleSSAUse(CompilationUnit* cUnit, int* uses, int dalvikReg,
1166 int regIndex)
buzbee67bf8852011-08-17 17:51:35 -07001167{
buzbeee1965672012-03-11 18:39:19 -07001168 DCHECK((dalvikReg >= 0) && (dalvikReg < cUnit->numDalvikRegisters));
1169 uses[regIndex] = cUnit->vRegToSSAMap[dalvikReg];
buzbee67bf8852011-08-17 17:51:35 -07001170}
1171
1172/* Setup a new SSA register for a given Dalvik register */
buzbee31a4a6f2012-02-28 15:36:15 -08001173void handleSSADef(CompilationUnit* cUnit, int* defs, int dalvikReg,
1174 int regIndex)
buzbee67bf8852011-08-17 17:51:35 -07001175{
buzbeee1965672012-03-11 18:39:19 -07001176 DCHECK((dalvikReg >= 0) && (dalvikReg < cUnit->numDalvikRegisters));
1177 int ssaReg = addNewSReg(cUnit, dalvikReg);
1178 cUnit->vRegToSSAMap[dalvikReg] = ssaReg;
buzbee67bf8852011-08-17 17:51:35 -07001179 defs[regIndex] = ssaReg;
1180}
1181
buzbeeec5adf32011-09-11 15:25:43 -07001182/* Look up new SSA names for format_35c instructions */
buzbee31a4a6f2012-02-28 15:36:15 -08001183void dataFlowSSAFormat35C(CompilationUnit* cUnit, MIR* mir)
buzbee67bf8852011-08-17 17:51:35 -07001184{
1185 DecodedInstruction *dInsn = &mir->dalvikInsn;
1186 int numUses = dInsn->vA;
1187 int i;
1188
1189 mir->ssaRep->numUses = numUses;
buzbeeba938cb2012-02-03 14:47:55 -08001190 mir->ssaRep->uses = (int *)oatNew(cUnit, sizeof(int) * numUses, true,
buzbee5abfa3e2012-01-31 17:01:43 -08001191 kAllocDFInfo);
buzbeeed3e9302011-09-23 17:34:19 -07001192 // NOTE: will be filled in during type & size inference pass
buzbeeba938cb2012-02-03 14:47:55 -08001193 mir->ssaRep->fpUse = (bool *)oatNew(cUnit, sizeof(bool) * numUses, true,
buzbee5abfa3e2012-01-31 17:01:43 -08001194 kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001195
1196 for (i = 0; i < numUses; i++) {
1197 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->arg[i], i);
1198 }
1199}
1200
buzbeeec5adf32011-09-11 15:25:43 -07001201/* Look up new SSA names for format_3rc instructions */
buzbee31a4a6f2012-02-28 15:36:15 -08001202void dataFlowSSAFormat3RC(CompilationUnit* cUnit, MIR* mir)
buzbee67bf8852011-08-17 17:51:35 -07001203{
1204 DecodedInstruction *dInsn = &mir->dalvikInsn;
1205 int numUses = dInsn->vA;
1206 int i;
1207
1208 mir->ssaRep->numUses = numUses;
buzbeeba938cb2012-02-03 14:47:55 -08001209 mir->ssaRep->uses = (int *)oatNew(cUnit, sizeof(int) * numUses, true,
buzbee5abfa3e2012-01-31 17:01:43 -08001210 kAllocDFInfo);
buzbeeed3e9302011-09-23 17:34:19 -07001211 // NOTE: will be filled in during type & size inference pass
buzbeeba938cb2012-02-03 14:47:55 -08001212 mir->ssaRep->fpUse = (bool *)oatNew(cUnit, sizeof(bool) * numUses, true,
buzbee5abfa3e2012-01-31 17:01:43 -08001213 kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001214
1215 for (i = 0; i < numUses; i++) {
1216 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC+i, i);
1217 }
1218}
1219
1220/* Entry function to convert a block into SSA representation */
1221bool oatDoSSAConversion(CompilationUnit* cUnit, BasicBlock* bb)
1222{
1223 MIR* mir;
1224
1225 if (bb->dataFlowInfo == NULL) return false;
1226
1227 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1228 mir->ssaRep = (struct SSARepresentation *)
buzbeeba938cb2012-02-03 14:47:55 -08001229 oatNew(cUnit, sizeof(SSARepresentation), true, kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001230
1231 int dfAttributes =
1232 oatDataFlowAttributes[mir->dalvikInsn.opcode];
1233
buzbeef0cde542011-09-13 14:55:02 -07001234 // If not a pseudo-op, note non-leaf or can throw
Elliott Hughesadb8c672012-03-06 16:49:32 -08001235 if (static_cast<int>(mir->dalvikInsn.opcode) < static_cast<int>(kNumPackedOpcodes)) {
1236 int flags = Instruction::Flags(mir->dalvikInsn.opcode);
buzbeecefd1872011-09-09 09:59:52 -07001237
Elliott Hughesadb8c672012-03-06 16:49:32 -08001238 if (flags & Instruction::kThrow) {
buzbeef0cde542011-09-13 14:55:02 -07001239 cUnit->attrs &= ~METHOD_IS_THROW_FREE;
1240 }
buzbeecefd1872011-09-09 09:59:52 -07001241
Elliott Hughesadb8c672012-03-06 16:49:32 -08001242 if (flags & Instruction::kInvoke) {
buzbeef0cde542011-09-13 14:55:02 -07001243 cUnit->attrs &= ~METHOD_IS_LEAF;
1244 }
buzbeecefd1872011-09-09 09:59:52 -07001245 }
1246
buzbee67bf8852011-08-17 17:51:35 -07001247 int numUses = 0;
1248
1249 if (dfAttributes & DF_FORMAT_35C) {
1250 dataFlowSSAFormat35C(cUnit, mir);
1251 continue;
1252 }
1253
1254 if (dfAttributes & DF_FORMAT_3RC) {
1255 dataFlowSSAFormat3RC(cUnit, mir);
1256 continue;
1257 }
1258
1259 if (dfAttributes & DF_HAS_USES) {
1260 if (dfAttributes & DF_UA) {
1261 numUses++;
1262 } else if (dfAttributes & DF_UA_WIDE) {
1263 numUses += 2;
1264 }
1265 if (dfAttributes & DF_UB) {
1266 numUses++;
1267 } else if (dfAttributes & DF_UB_WIDE) {
1268 numUses += 2;
1269 }
1270 if (dfAttributes & DF_UC) {
1271 numUses++;
1272 } else if (dfAttributes & DF_UC_WIDE) {
1273 numUses += 2;
1274 }
1275 }
1276
1277 if (numUses) {
1278 mir->ssaRep->numUses = numUses;
buzbeeba938cb2012-02-03 14:47:55 -08001279 mir->ssaRep->uses = (int *)oatNew(cUnit, sizeof(int) * numUses,
buzbee5abfa3e2012-01-31 17:01:43 -08001280 false, kAllocDFInfo);
buzbeeba938cb2012-02-03 14:47:55 -08001281 mir->ssaRep->fpUse = (bool *)oatNew(cUnit, sizeof(bool) * numUses,
buzbee5abfa3e2012-01-31 17:01:43 -08001282 false, kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001283 }
1284
1285 int numDefs = 0;
1286
1287 if (dfAttributes & DF_HAS_DEFS) {
1288 numDefs++;
1289 if (dfAttributes & DF_DA_WIDE) {
1290 numDefs++;
1291 }
1292 }
1293
1294 if (numDefs) {
1295 mir->ssaRep->numDefs = numDefs;
buzbeeba938cb2012-02-03 14:47:55 -08001296 mir->ssaRep->defs = (int *)oatNew(cUnit, sizeof(int) * numDefs,
buzbee5abfa3e2012-01-31 17:01:43 -08001297 false, kAllocDFInfo);
buzbeeba938cb2012-02-03 14:47:55 -08001298 mir->ssaRep->fpDef = (bool *)oatNew(cUnit, sizeof(bool) * numDefs,
buzbee5abfa3e2012-01-31 17:01:43 -08001299 false, kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001300 }
1301
1302 DecodedInstruction *dInsn = &mir->dalvikInsn;
1303
1304 if (dfAttributes & DF_HAS_USES) {
1305 numUses = 0;
1306 if (dfAttributes & DF_UA) {
1307 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
1308 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA, numUses++);
1309 } else if (dfAttributes & DF_UA_WIDE) {
1310 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
1311 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA, numUses++);
1312 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
1313 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA+1, numUses++);
1314 }
1315 if (dfAttributes & DF_UB) {
1316 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
1317 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB, numUses++);
1318 } else if (dfAttributes & DF_UB_WIDE) {
1319 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
1320 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB, numUses++);
1321 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
1322 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB+1, numUses++);
1323 }
1324 if (dfAttributes & DF_UC) {
1325 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
1326 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC, numUses++);
1327 } else if (dfAttributes & DF_UC_WIDE) {
1328 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
1329 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC, numUses++);
1330 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
1331 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC+1, numUses++);
1332 }
1333 }
1334 if (dfAttributes & DF_HAS_DEFS) {
1335 mir->ssaRep->fpDef[0] = dfAttributes & DF_FP_A;
1336 handleSSADef(cUnit, mir->ssaRep->defs, dInsn->vA, 0);
1337 if (dfAttributes & DF_DA_WIDE) {
1338 mir->ssaRep->fpDef[1] = dfAttributes & DF_FP_A;
1339 handleSSADef(cUnit, mir->ssaRep->defs, dInsn->vA+1, 1);
1340 }
1341 }
1342 }
1343
buzbee5abfa3e2012-01-31 17:01:43 -08001344 if (!cUnit->disableDataflow) {
1345 /*
1346 * Take a snapshot of Dalvik->SSA mapping at the end of each block. The
1347 * input to PHI nodes can be derived from the snapshot of all
1348 * predecessor blocks.
1349 */
buzbeee1965672012-03-11 18:39:19 -07001350 bb->dataFlowInfo->vRegToSSAMap =
buzbeeba938cb2012-02-03 14:47:55 -08001351 (int *)oatNew(cUnit, sizeof(int) * cUnit->numDalvikRegisters, false,
buzbee5abfa3e2012-01-31 17:01:43 -08001352 kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001353
buzbeee1965672012-03-11 18:39:19 -07001354 memcpy(bb->dataFlowInfo->vRegToSSAMap, cUnit->vRegToSSAMap,
buzbee5abfa3e2012-01-31 17:01:43 -08001355 sizeof(int) * cUnit->numDalvikRegisters);
1356 }
buzbee67bf8852011-08-17 17:51:35 -07001357 return true;
1358}
1359
1360/* Setup a constant value for opcodes thare have the DF_SETS_CONST attribute */
buzbee31a4a6f2012-02-28 15:36:15 -08001361void setConstant(CompilationUnit* cUnit, int ssaReg, int value)
buzbee67bf8852011-08-17 17:51:35 -07001362{
buzbeeba938cb2012-02-03 14:47:55 -08001363 oatSetBit(cUnit, cUnit->isConstantV, ssaReg);
buzbee67bf8852011-08-17 17:51:35 -07001364 cUnit->constantValues[ssaReg] = value;
1365}
1366
1367bool oatDoConstantPropagation(CompilationUnit* cUnit, BasicBlock* bb)
1368{
1369 MIR* mir;
1370 ArenaBitVector *isConstantV = cUnit->isConstantV;
1371
1372 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1373 int dfAttributes =
1374 oatDataFlowAttributes[mir->dalvikInsn.opcode];
1375
1376 DecodedInstruction *dInsn = &mir->dalvikInsn;
1377
1378 if (!(dfAttributes & DF_HAS_DEFS)) continue;
1379
1380 /* Handle instructions that set up constants directly */
1381 if (dfAttributes & DF_SETS_CONST) {
1382 if (dfAttributes & DF_DA) {
1383 switch (dInsn->opcode) {
Elliott Hughesadb8c672012-03-06 16:49:32 -08001384 case Instruction::CONST_4:
1385 case Instruction::CONST_16:
1386 case Instruction::CONST:
buzbee67bf8852011-08-17 17:51:35 -07001387 setConstant(cUnit, mir->ssaRep->defs[0], dInsn->vB);
1388 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -08001389 case Instruction::CONST_HIGH16:
buzbee67bf8852011-08-17 17:51:35 -07001390 setConstant(cUnit, mir->ssaRep->defs[0],
1391 dInsn->vB << 16);
1392 break;
1393 default:
1394 break;
1395 }
1396 } else if (dfAttributes & DF_DA_WIDE) {
1397 switch (dInsn->opcode) {
Elliott Hughesadb8c672012-03-06 16:49:32 -08001398 case Instruction::CONST_WIDE_16:
1399 case Instruction::CONST_WIDE_32:
buzbee67bf8852011-08-17 17:51:35 -07001400 setConstant(cUnit, mir->ssaRep->defs[0], dInsn->vB);
1401 setConstant(cUnit, mir->ssaRep->defs[1], 0);
1402 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -08001403 case Instruction::CONST_WIDE:
buzbee67bf8852011-08-17 17:51:35 -07001404 setConstant(cUnit, mir->ssaRep->defs[0],
1405 (int) dInsn->vB_wide);
1406 setConstant(cUnit, mir->ssaRep->defs[1],
1407 (int) (dInsn->vB_wide >> 32));
1408 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -08001409 case Instruction::CONST_WIDE_HIGH16:
buzbee67bf8852011-08-17 17:51:35 -07001410 setConstant(cUnit, mir->ssaRep->defs[0], 0);
1411 setConstant(cUnit, mir->ssaRep->defs[1],
1412 dInsn->vB << 16);
1413 break;
1414 default:
1415 break;
1416 }
1417 }
1418 /* Handle instructions that set up constants directly */
1419 } else if (dfAttributes & DF_IS_MOVE) {
1420 int i;
1421
1422 for (i = 0; i < mir->ssaRep->numUses; i++) {
1423 if (!oatIsBitSet(isConstantV, mir->ssaRep->uses[i])) break;
1424 }
1425 /* Move a register holding a constant to another register */
1426 if (i == mir->ssaRep->numUses) {
1427 setConstant(cUnit, mir->ssaRep->defs[0],
1428 cUnit->constantValues[mir->ssaRep->uses[0]]);
1429 if (dfAttributes & DF_DA_WIDE) {
1430 setConstant(cUnit, mir->ssaRep->defs[1],
1431 cUnit->constantValues[mir->ssaRep->uses[1]]);
1432 }
1433 }
1434 }
1435 }
1436 /* TODO: implement code to handle arithmetic operations */
1437 return true;
1438}
1439
1440/* Setup the basic data structures for SSA conversion */
1441void oatInitializeSSAConversion(CompilationUnit* cUnit)
1442{
1443 int i;
Ian Rogersa3760aa2011-11-14 14:32:37 -08001444 int numDalvikReg = cUnit->numDalvikRegisters;
buzbee67bf8852011-08-17 17:51:35 -07001445
buzbeee1965672012-03-11 18:39:19 -07001446 cUnit->ssaBaseVRegs = (GrowableList *)oatNew(cUnit, sizeof(GrowableList),
1447 false, kAllocDFInfo);
1448 cUnit->ssaSubscripts = (GrowableList *)oatNew(cUnit, sizeof(GrowableList),
1449 false, kAllocDFInfo);
1450 // Create the ssa mappings, estimating the max size
1451 oatInitGrowableList(cUnit, cUnit->ssaBaseVRegs,
1452 numDalvikReg + cUnit->defCount + 128,
1453 kListSSAtoDalvikMap);
1454 oatInitGrowableList(cUnit, cUnit->ssaSubscripts,
buzbee5abfa3e2012-01-31 17:01:43 -08001455 numDalvikReg + cUnit->defCount + 128,
1456 kListSSAtoDalvikMap);
buzbee67bf8852011-08-17 17:51:35 -07001457 /*
1458 * Initial number of SSA registers is equal to the number of Dalvik
1459 * registers.
1460 */
1461 cUnit->numSSARegs = numDalvikReg;
1462
1463 /*
1464 * Initialize the SSA2Dalvik map list. For the first numDalvikReg elements,
1465 * the subscript is 0 so we use the ENCODE_REG_SUB macro to encode the value
1466 * into "(0 << 16) | i"
1467 */
1468 for (i = 0; i < numDalvikReg; i++) {
buzbeee1965672012-03-11 18:39:19 -07001469 oatInsertGrowableList(cUnit, cUnit->ssaBaseVRegs, i);
1470 oatInsertGrowableList(cUnit, cUnit->ssaSubscripts, 0);
buzbee67bf8852011-08-17 17:51:35 -07001471 }
1472
1473 /*
buzbeee1965672012-03-11 18:39:19 -07001474 * Initialize the DalvikToSSAMap map. There is one entry for each
1475 * Dalvik register, and the SSA names for those are the same.
buzbee67bf8852011-08-17 17:51:35 -07001476 */
buzbeee1965672012-03-11 18:39:19 -07001477 cUnit->vRegToSSAMap = (int *)oatNew(cUnit, sizeof(int) * numDalvikReg,
buzbee5abfa3e2012-01-31 17:01:43 -08001478 false, kAllocDFInfo);
buzbeef0cde542011-09-13 14:55:02 -07001479 /* Keep track of the higest def for each dalvik reg */
buzbeeba938cb2012-02-03 14:47:55 -08001480 cUnit->SSALastDefs = (int *)oatNew(cUnit, sizeof(int) * numDalvikReg,
buzbee5abfa3e2012-01-31 17:01:43 -08001481 false, kAllocDFInfo);
buzbeef0cde542011-09-13 14:55:02 -07001482
buzbee67bf8852011-08-17 17:51:35 -07001483 for (i = 0; i < numDalvikReg; i++) {
buzbeee1965672012-03-11 18:39:19 -07001484 cUnit->vRegToSSAMap[i] = i;
buzbeef0cde542011-09-13 14:55:02 -07001485 cUnit->SSALastDefs[i] = 0;
buzbee67bf8852011-08-17 17:51:35 -07001486 }
1487
buzbeee1965672012-03-11 18:39:19 -07001488 /* Add ssa reg for Method* */
1489 cUnit->methodSReg = addNewSReg(cUnit, SSA_METHOD_BASEREG);
1490
buzbee67bf8852011-08-17 17:51:35 -07001491 /*
1492 * Allocate the BasicBlockDataFlow structure for the entry and code blocks
1493 */
1494 GrowableListIterator iterator;
1495
1496 oatGrowableListIteratorInit(&cUnit->blockList, &iterator);
1497
1498 while (true) {
1499 BasicBlock* bb = (BasicBlock *) oatGrowableListIteratorNext(&iterator);
1500 if (bb == NULL) break;
1501 if (bb->hidden == true) continue;
1502 if (bb->blockType == kDalvikByteCode ||
1503 bb->blockType == kEntryBlock ||
1504 bb->blockType == kExitBlock) {
1505 bb->dataFlowInfo = (BasicBlockDataFlow *)
buzbeeba938cb2012-02-03 14:47:55 -08001506 oatNew(cUnit, sizeof(BasicBlockDataFlow),
buzbee5abfa3e2012-01-31 17:01:43 -08001507 true, kAllocDFInfo);
buzbee67bf8852011-08-17 17:51:35 -07001508 }
1509 }
1510}
1511
1512/* Clear the visited flag for each BB */
buzbee31a4a6f2012-02-28 15:36:15 -08001513bool oatClearVisitedFlag(struct CompilationUnit* cUnit, struct BasicBlock* bb)
buzbee67bf8852011-08-17 17:51:35 -07001514{
1515 bb->visited = false;
1516 return true;
1517}
1518
1519void oatDataFlowAnalysisDispatcher(CompilationUnit* cUnit,
1520 bool (*func)(CompilationUnit*, BasicBlock*),
1521 DataFlowAnalysisMode dfaMode,
1522 bool isIterative)
1523{
1524 bool change = true;
1525
1526 while (change) {
1527 change = false;
1528
buzbee5b537102012-01-17 17:33:47 -08001529 switch (dfaMode) {
buzbee67bf8852011-08-17 17:51:35 -07001530 /* Scan all blocks and perform the operations specified in func */
buzbee5b537102012-01-17 17:33:47 -08001531 case kAllNodes:
1532 {
1533 GrowableListIterator iterator;
1534 oatGrowableListIteratorInit(&cUnit->blockList, &iterator);
1535 while (true) {
1536 BasicBlock* bb =
1537 (BasicBlock *) oatGrowableListIteratorNext(&iterator);
1538 if (bb == NULL) break;
1539 if (bb->hidden == true) continue;
1540 change |= (*func)(cUnit, bb);
1541 }
buzbee67bf8852011-08-17 17:51:35 -07001542 }
buzbee5b537102012-01-17 17:33:47 -08001543 break;
1544 /* Scan reachable blocks and perform the ops specified in func. */
1545 case kReachableNodes:
1546 {
1547 int numReachableBlocks = cUnit->numReachableBlocks;
1548 int idx;
1549 const GrowableList *blockList = &cUnit->blockList;
buzbee67bf8852011-08-17 17:51:35 -07001550
buzbee5b537102012-01-17 17:33:47 -08001551 for (idx = 0; idx < numReachableBlocks; idx++) {
1552 int blockIdx = cUnit->dfsOrder.elemList[idx];
1553 BasicBlock* bb =
1554 (BasicBlock *) oatGrowableListGetElement(blockList,
1555 blockIdx);
1556 change |= (*func)(cUnit, bb);
1557 }
buzbee67bf8852011-08-17 17:51:35 -07001558 }
buzbee5b537102012-01-17 17:33:47 -08001559 break;
buzbee67bf8852011-08-17 17:51:35 -07001560
buzbee5b537102012-01-17 17:33:47 -08001561 /* Scan reachable blocks by pre-order dfs and invoke func on each. */
1562 case kPreOrderDFSTraversal:
1563 {
1564 int numReachableBlocks = cUnit->numReachableBlocks;
1565 int idx;
1566 const GrowableList *blockList = &cUnit->blockList;
buzbee67bf8852011-08-17 17:51:35 -07001567
buzbee5b537102012-01-17 17:33:47 -08001568 for (idx = 0; idx < numReachableBlocks; idx++) {
1569 int dfsIdx = cUnit->dfsOrder.elemList[idx];
1570 BasicBlock* bb =
1571 (BasicBlock *) oatGrowableListGetElement(blockList,
1572 dfsIdx);
1573 change |= (*func)(cUnit, bb);
1574 }
buzbee67bf8852011-08-17 17:51:35 -07001575 }
buzbee5b537102012-01-17 17:33:47 -08001576 break;
1577 /* Scan reachable blocks post-order dfs and invoke func on each. */
1578 case kPostOrderDFSTraversal:
1579 {
1580 int numReachableBlocks = cUnit->numReachableBlocks;
1581 int idx;
1582 const GrowableList *blockList = &cUnit->blockList;
buzbee67bf8852011-08-17 17:51:35 -07001583
buzbee5b537102012-01-17 17:33:47 -08001584 for (idx = numReachableBlocks - 1; idx >= 0; idx--) {
1585 int dfsIdx = cUnit->dfsOrder.elemList[idx];
1586 BasicBlock* bb =
1587 (BasicBlock *) oatGrowableListGetElement(blockList,
1588 dfsIdx);
1589 change |= (*func)(cUnit, bb);
1590 }
buzbee67bf8852011-08-17 17:51:35 -07001591 }
buzbee5b537102012-01-17 17:33:47 -08001592 break;
1593 /* Scan reachable post-order dom tree and invoke func on each. */
1594 case kPostOrderDOMTraversal:
1595 {
1596 int numReachableBlocks = cUnit->numReachableBlocks;
1597 int idx;
1598 const GrowableList *blockList = &cUnit->blockList;
1599
1600 for (idx = 0; idx < numReachableBlocks; idx++) {
1601 int domIdx = cUnit->domPostOrderTraversal.elemList[idx];
1602 BasicBlock* bb =
1603 (BasicBlock *) oatGrowableListGetElement(blockList,
1604 domIdx);
1605 change |= (*func)(cUnit, bb);
1606 }
1607 }
1608 break;
1609 /* Scan reachable blocks reverse post-order dfs, invoke func on each */
1610 case kReversePostOrderTraversal:
1611 {
1612 int numReachableBlocks = cUnit->numReachableBlocks;
1613 int idx;
1614 const GrowableList *blockList = &cUnit->blockList;
1615
1616 for (idx = numReachableBlocks - 1; idx >= 0; idx--) {
1617 int revIdx = cUnit->dfsPostOrder.elemList[idx];
1618 BasicBlock* bb =
1619 (BasicBlock *) oatGrowableListGetElement(blockList,
1620 revIdx);
1621 change |= (*func)(cUnit, bb);
1622 }
1623 }
1624 break;
1625 default:
1626 LOG(FATAL) << "Unknown traversal mode " << (int)dfaMode;
buzbee67bf8852011-08-17 17:51:35 -07001627 }
1628 /* If isIterative is false, exit the loop after the first iteration */
1629 change &= isIterative;
1630 }
1631}
buzbee43a36422011-09-14 14:00:13 -07001632
buzbeee1965672012-03-11 18:39:19 -07001633/* Advance to next strictly dominated MIR node in an extended basic block */
buzbee239c4e72012-03-16 08:42:29 -07001634MIR* advanceMIR(CompilationUnit* cUnit, BasicBlock** pBb, MIR* mir, ArenaBitVector* bv,
1635 bool clearMark) {
buzbeee1965672012-03-11 18:39:19 -07001636 BasicBlock* bb = *pBb;
1637 if (mir != NULL) {
1638 mir = mir->next;
1639 if (mir == NULL) {
1640 bb = bb->fallThrough;
1641 if ((bb == NULL) || bb->predecessors->numUsed != 1) {
1642 mir = NULL;
1643 } else {
1644 if (bv) {
1645 oatSetBit(cUnit, bv, bb->id);
1646 }
1647 *pBb = bb;
1648 mir = bb->firstMIRInsn;
1649 }
1650 }
1651 }
buzbee239c4e72012-03-16 08:42:29 -07001652 if (mir && clearMark) {
1653 mir->optimizationFlags &= ~MIR_MARK;
1654 }
buzbeee1965672012-03-11 18:39:19 -07001655 return mir;
1656}
1657
buzbeefc9e6fa2012-03-23 15:14:29 -07001658/*
1659 * To be used at an invoke mir. If the logically next mir node represents
1660 * a move-result, return it. Else, return NULL. If a move-result exists,
1661 * it is required to immediately follow the invoke with no intervening
1662 * opcodes or incoming arcs. However, if the result of the invoke is not
1663 * used, a move-result may not be present.
1664 */
1665MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1666 bool wide)
1667{
1668 BasicBlock* tbb = bb;
1669 mir = advanceMIR(cUnit, &tbb, mir, NULL, false);
1670 while (mir != NULL) {
1671 if (!wide && mir->dalvikInsn.opcode == Instruction::MOVE_RESULT) {
1672 break;
1673 }
1674 if (wide && mir->dalvikInsn.opcode == Instruction::MOVE_RESULT_WIDE) {
1675 break;
1676 }
1677 // Keep going if pseudo op, otherwise terminate
1678 if (mir->dalvikInsn.opcode < static_cast<Instruction::Code>(kNumPackedOpcodes)) {
1679 mir = NULL;
1680 } else {
1681 mir = advanceMIR(cUnit, &tbb, mir, NULL, false);
1682 }
1683 }
1684 return mir;
1685}
1686
buzbee239c4e72012-03-16 08:42:29 -07001687void squashDupRangeChecks(CompilationUnit* cUnit, BasicBlock** pBp, MIR* mir,
1688 int arraySreg, int indexSreg)
1689{
1690 while (true) {
1691 mir = advanceMIR(cUnit, pBp, mir, NULL, false);
1692 if (!mir) {
1693 break;
1694 }
1695 if ((mir->ssaRep == NULL) ||
1696 (mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
1697 continue;
1698 }
1699 int checkArray = INVALID_SREG;
1700 int checkIndex = INVALID_SREG;
Elliott Hughesb25c3f62012-03-26 16:35:06 -07001701 switch (mir->dalvikInsn.opcode) {
buzbee239c4e72012-03-16 08:42:29 -07001702 case Instruction::AGET:
1703 case Instruction::AGET_OBJECT:
1704 case Instruction::AGET_BOOLEAN:
1705 case Instruction::AGET_BYTE:
1706 case Instruction::AGET_CHAR:
1707 case Instruction::AGET_SHORT:
1708 case Instruction::AGET_WIDE:
1709 checkArray = mir->ssaRep->uses[0];
1710 checkIndex = mir->ssaRep->uses[1];
1711 break;
1712 break;
1713 case Instruction::APUT:
1714 case Instruction::APUT_OBJECT:
1715 case Instruction::APUT_SHORT:
1716 case Instruction::APUT_CHAR:
1717 case Instruction::APUT_BYTE:
1718 case Instruction::APUT_BOOLEAN:
1719 checkArray = mir->ssaRep->uses[1];
1720 checkIndex = mir->ssaRep->uses[2];
1721 break;
1722 case Instruction::APUT_WIDE:
1723 checkArray = mir->ssaRep->uses[2];
1724 checkIndex = mir->ssaRep->uses[3];
1725 default:
1726 break;
1727 }
1728 if (checkArray == INVALID_SREG) {
1729 continue;
1730 }
1731 if ((arraySreg == checkArray) && (indexSreg == checkIndex)) {
1732 if (cUnit->printMe) {
1733 LOG(INFO) << "Squashing range check @ 0x" << std::hex
1734 << mir->offset;
1735 }
1736 mir->optimizationFlags |= MIR_IGNORE_RANGE_CHECK;
1737 }
1738 }
1739}
1740
buzbeee1965672012-03-11 18:39:19 -07001741/* Allocate a compiler temp, return Sreg. Reuse existing if no conflict */
1742int allocCompilerTempSreg(CompilationUnit* cUnit, ArenaBitVector* bv)
1743{
1744 for (int i = 0; i < cUnit->numCompilerTemps; i++) {
1745 CompilerTemp* ct = (CompilerTemp*)cUnit->compilerTemps.elemList[i];
1746 ArenaBitVector* tBv = ct->bv;
1747 if (!oatTestBitVectors(bv, tBv)) {
1748 // Combine live maps and reuse existing temp
1749 oatUnifyBitVectors(tBv, tBv, bv);
1750 return ct->sReg;
1751 }
1752 }
1753
1754 // Create a new compiler temp & associated live bitmap
1755 CompilerTemp* ct = (CompilerTemp*)oatNew(cUnit, sizeof(CompilerTemp),
1756 true, kAllocMisc);
1757 ArenaBitVector *nBv = oatAllocBitVector(cUnit, cUnit->numBlocks, true,
1758 kBitMapMisc);
1759 oatCopyBitVector(nBv, bv);
1760 ct->bv = nBv;
1761 ct->sReg = addNewSReg(cUnit, SSA_CTEMP_BASEREG - cUnit->numCompilerTemps);
1762 cUnit->numCompilerTemps++;
1763 oatInsertGrowableList(cUnit, &cUnit->compilerTemps, (intptr_t)ct);
1764 DCHECK_EQ(cUnit->numCompilerTemps, (int)cUnit->compilerTemps.numUsed);
1765 return ct->sReg;
1766}
1767
1768/* Creata a new MIR node for a new pseudo op. */
1769MIR* rawMIR(CompilationUnit* cUnit, Instruction::Code opcode, int defs, int uses)
1770{
1771 MIR* res = (MIR*)oatNew( cUnit, sizeof(MIR), true, kAllocMIR);
1772 res->ssaRep =(struct SSARepresentation *)
1773 oatNew(cUnit, sizeof(SSARepresentation), true, kAllocDFInfo);
1774 if (uses) {
1775 res->ssaRep->numUses = uses;
1776 res->ssaRep->uses = (int*)oatNew(cUnit, sizeof(int) * uses, false, kAllocDFInfo);
1777 }
1778 if (defs) {
1779 res->ssaRep->numDefs = defs;
1780 res->ssaRep->defs = (int*)oatNew(cUnit, sizeof(int) * defs, false, kAllocDFInfo);
1781 res->ssaRep->fpDef = (bool*)oatNew(cUnit, sizeof(bool) * defs, true, kAllocDFInfo);
1782 }
1783 res->dalvikInsn.opcode = opcode;
1784 return res;
1785}
1786
1787/* Do some MIR-level basic block optimizations */
1788bool basicBlockOpt(CompilationUnit* cUnit, BasicBlock* bb)
1789{
1790 int numTemps = 0;
1791
1792 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1793 // Look for interesting opcodes, skip otherwise
buzbee239c4e72012-03-16 08:42:29 -07001794 Instruction::Code opcode = mir->dalvikInsn.opcode;
Elliott Hughesb25c3f62012-03-26 16:35:06 -07001795 switch (opcode) {
buzbee239c4e72012-03-16 08:42:29 -07001796 case Instruction::AGET:
1797 case Instruction::AGET_OBJECT:
1798 case Instruction::AGET_BOOLEAN:
1799 case Instruction::AGET_BYTE:
1800 case Instruction::AGET_CHAR:
1801 case Instruction::AGET_SHORT:
1802 case Instruction::AGET_WIDE:
1803 if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
1804 int arrSreg = mir->ssaRep->uses[0];
1805 int idxSreg = mir->ssaRep->uses[1];
1806 BasicBlock* tbb = bb;
1807 squashDupRangeChecks(cUnit, &tbb, mir, arrSreg, idxSreg);
1808 }
1809 break;
1810 case Instruction::APUT:
1811 case Instruction::APUT_OBJECT:
1812 case Instruction::APUT_SHORT:
1813 case Instruction::APUT_CHAR:
1814 case Instruction::APUT_BYTE:
1815 case Instruction::APUT_BOOLEAN:
1816 case Instruction::APUT_WIDE:
1817 if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
1818 int start = (opcode == Instruction::APUT_WIDE) ? 2 : 1;
1819 int arrSreg = mir->ssaRep->uses[start];
1820 int idxSreg = mir->ssaRep->uses[start + 1];
1821 BasicBlock* tbb = bb;
1822 squashDupRangeChecks(cUnit, &tbb, mir, arrSreg, idxSreg);
1823 }
1824 break;
buzbee239c4e72012-03-16 08:42:29 -07001825 case Instruction::CMPL_FLOAT:
1826 case Instruction::CMPL_DOUBLE:
1827 case Instruction::CMPG_FLOAT:
1828 case Instruction::CMPG_DOUBLE:
1829 case Instruction::CMP_LONG:
buzbeee1965672012-03-11 18:39:19 -07001830 // TODO: Check for and fuse preceeding comparison
1831 break;
1832 default:
1833 break;
1834 }
1835 }
1836
1837 if (numTemps > cUnit->numCompilerTemps) {
1838 cUnit->numCompilerTemps = numTemps;
1839 }
1840 return true;
1841}
1842
buzbee31a4a6f2012-02-28 15:36:15 -08001843bool nullCheckEliminationInit(struct CompilationUnit* cUnit,
1844 struct BasicBlock* bb)
buzbee43a36422011-09-14 14:00:13 -07001845{
1846 if (bb->dataFlowInfo == NULL) return false;
1847 bb->dataFlowInfo->endingNullCheckV =
buzbeeba938cb2012-02-03 14:47:55 -08001848 oatAllocBitVector(cUnit, cUnit->numSSARegs, false, kBitMapNullCheck);
buzbee43a36422011-09-14 14:00:13 -07001849 oatClearAllBits(bb->dataFlowInfo->endingNullCheckV);
1850 return true;
1851}
1852
1853/* Eliminate unnecessary null checks for a basic block. */
buzbee31a4a6f2012-02-28 15:36:15 -08001854bool eliminateNullChecks( struct CompilationUnit* cUnit, struct BasicBlock* bb)
buzbee43a36422011-09-14 14:00:13 -07001855{
1856 if (bb->dataFlowInfo == NULL) return false;
buzbee5abfa3e2012-01-31 17:01:43 -08001857
buzbee43a36422011-09-14 14:00:13 -07001858 /*
1859 * Set initial state. Be conservative with catch
1860 * blocks and start with no assumptions about null check
1861 * status (except for "this").
1862 */
buzbee43a36422011-09-14 14:00:13 -07001863 if ((bb->blockType == kEntryBlock) | bb->catchEntry) {
1864 oatClearAllBits(cUnit->tempSSARegisterV);
Elliott Hughes11d1b0c2012-01-23 16:57:47 -08001865 if ((cUnit->access_flags & kAccStatic) == 0) {
buzbee43a36422011-09-14 14:00:13 -07001866 // If non-static method, mark "this" as non-null
Ian Rogersa3760aa2011-11-14 14:32:37 -08001867 int thisReg = cUnit->numDalvikRegisters - cUnit->numIns;
buzbeeba938cb2012-02-03 14:47:55 -08001868 oatSetBit(cUnit, cUnit->tempSSARegisterV, thisReg);
buzbee43a36422011-09-14 14:00:13 -07001869 }
1870 } else {
1871 // Starting state is intesection of all incoming arcs
buzbee5abfa3e2012-01-31 17:01:43 -08001872 GrowableListIterator iter;
1873 oatGrowableListIteratorInit(bb->predecessors, &iter);
1874 BasicBlock* predBB = (BasicBlock*)oatGrowableListIteratorNext(&iter);
1875 DCHECK(predBB != NULL);
buzbee43a36422011-09-14 14:00:13 -07001876 oatCopyBitVector(cUnit->tempSSARegisterV,
1877 predBB->dataFlowInfo->endingNullCheckV);
1878 while (true) {
buzbee5abfa3e2012-01-31 17:01:43 -08001879 predBB = (BasicBlock*)oatGrowableListIteratorNext(&iter);
1880 if (!predBB) break;
buzbeeaad72012011-09-21 21:52:09 -07001881 if ((predBB->dataFlowInfo == NULL) ||
1882 (predBB->dataFlowInfo->endingNullCheckV == NULL)) {
1883 continue;
1884 }
buzbee43a36422011-09-14 14:00:13 -07001885 oatIntersectBitVectors(cUnit->tempSSARegisterV,
1886 cUnit->tempSSARegisterV,
1887 predBB->dataFlowInfo->endingNullCheckV);
1888 }
1889 }
1890
1891 // Walk through the instruction in the block, updating as necessary
1892 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1893 if (mir->ssaRep == NULL) {
1894 continue;
1895 }
1896 int dfAttributes =
1897 oatDataFlowAttributes[mir->dalvikInsn.opcode];
1898
1899 // Mark target of NEW* as non-null
1900 if (dfAttributes & DF_NON_NULL_DST) {
buzbeeba938cb2012-02-03 14:47:55 -08001901 oatSetBit(cUnit, cUnit->tempSSARegisterV, mir->ssaRep->defs[0]);
buzbee43a36422011-09-14 14:00:13 -07001902 }
1903
1904 // Mark non-null returns from invoke-style NEW*
1905 if (dfAttributes & DF_NON_NULL_RET) {
1906 MIR* nextMir = mir->next;
Elliott Hughesadb8c672012-03-06 16:49:32 -08001907 // Next should be an MOVE_RESULT_OBJECT
1908 if (nextMir && nextMir->dalvikInsn.opcode == Instruction::MOVE_RESULT_OBJECT) {
buzbee43a36422011-09-14 14:00:13 -07001909 // Mark as null checked
buzbeeba938cb2012-02-03 14:47:55 -08001910 oatSetBit(cUnit, cUnit->tempSSARegisterV,
1911 nextMir->ssaRep->defs[0]);
buzbee43a36422011-09-14 14:00:13 -07001912 } else {
1913 if (nextMir) {
1914 LOG(WARNING) << "Unexpected opcode following new: " <<
1915 (int)nextMir->dalvikInsn.opcode;
buzbee949f56e2011-10-06 11:05:45 -07001916 } else if (bb->fallThrough) {
1917 // Look in next basic block
1918 struct BasicBlock* nextBB = bb->fallThrough;
1919 for (MIR* tmir = nextBB->firstMIRInsn; tmir;
Elliott Hughesb25c3f62012-03-26 16:35:06 -07001920 tmir =tmir->next) {
buzbee949f56e2011-10-06 11:05:45 -07001921 if ((int)tmir->dalvikInsn.opcode >= (int)kMirOpFirst) {
1922 continue;
1923 }
Elliott Hughesadb8c672012-03-06 16:49:32 -08001924 // First non-pseudo should be MOVE_RESULT_OBJECT
1925 if (tmir->dalvikInsn.opcode == Instruction::MOVE_RESULT_OBJECT) {
buzbee949f56e2011-10-06 11:05:45 -07001926 // Mark as null checked
buzbeeba938cb2012-02-03 14:47:55 -08001927 oatSetBit(cUnit, cUnit->tempSSARegisterV,
buzbee949f56e2011-10-06 11:05:45 -07001928 tmir->ssaRep->defs[0]);
1929 } else {
1930 LOG(WARNING) << "Unexpected op after new: " <<
1931 (int)tmir->dalvikInsn.opcode;
1932 }
1933 break;
1934 }
buzbee43a36422011-09-14 14:00:13 -07001935 }
1936 }
1937 }
1938
1939 /*
1940 * Propagate nullcheck state on register copies (including
1941 * Phi pseudo copies. For the latter, nullcheck state is
1942 * the "and" of all the Phi's operands.
1943 */
1944 if (dfAttributes & (DF_NULL_TRANSFER_0 | DF_NULL_TRANSFER_N)) {
1945 int tgtSreg = mir->ssaRep->defs[0];
1946 int operands = (dfAttributes & DF_NULL_TRANSFER_0) ? 1 :
1947 mir->ssaRep->numUses;
1948 bool nullChecked = true;
1949 for (int i = 0; i < operands; i++) {
1950 nullChecked &= oatIsBitSet(cUnit->tempSSARegisterV,
1951 mir->ssaRep->uses[i]);
1952 }
1953 if (nullChecked) {
buzbeeba938cb2012-02-03 14:47:55 -08001954 oatSetBit(cUnit, cUnit->tempSSARegisterV, tgtSreg);
buzbee43a36422011-09-14 14:00:13 -07001955 }
1956 }
1957
1958 // Already nullchecked?
1959 if (dfAttributes & DF_HAS_NULL_CHKS) {
buzbee239c4e72012-03-16 08:42:29 -07001960 int srcIdx;
1961 if (dfAttributes & DF_NULL_CHK_1) {
1962 srcIdx = 1;
1963 } else if (dfAttributes & DF_NULL_CHK_2) {
1964 srcIdx = 2;
1965 } else {
1966 srcIdx = 0;
1967 }
1968 int srcSreg = mir->ssaRep->uses[srcIdx];
buzbee43a36422011-09-14 14:00:13 -07001969 if (oatIsBitSet(cUnit->tempSSARegisterV, srcSreg)) {
1970 // Eliminate the null check
1971 mir->optimizationFlags |= MIR_IGNORE_NULL_CHECK;
1972 } else {
1973 // Mark sReg as null-checked
buzbeeba938cb2012-02-03 14:47:55 -08001974 oatSetBit(cUnit, cUnit->tempSSARegisterV, srcSreg);
buzbee43a36422011-09-14 14:00:13 -07001975 }
1976 }
1977 }
1978
1979 // Did anything change?
1980 bool res = oatCompareBitVectors(bb->dataFlowInfo->endingNullCheckV,
1981 cUnit->tempSSARegisterV);
1982 if (res) {
1983 oatCopyBitVector(bb->dataFlowInfo->endingNullCheckV,
1984 cUnit->tempSSARegisterV);
1985 }
1986 return res;
1987}
1988
1989void oatMethodNullCheckElimination(CompilationUnit *cUnit)
1990{
1991 if (!(cUnit->disableOpt & (1 << kNullCheckElimination))) {
1992 DCHECK(cUnit->tempSSARegisterV != NULL);
1993 oatDataFlowAnalysisDispatcher(cUnit, nullCheckEliminationInit,
1994 kAllNodes,
1995 false /* isIterative */);
1996 oatDataFlowAnalysisDispatcher(cUnit, eliminateNullChecks,
1997 kPreOrderDFSTraversal,
1998 true /* isIterative */);
1999 }
2000}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -08002001
buzbeee1965672012-03-11 18:39:19 -07002002void oatMethodBasicBlockOptimization(CompilationUnit *cUnit)
2003{
buzbeee1965672012-03-11 18:39:19 -07002004 if (!(cUnit->disableOpt & (1 << kBBOpt))) {
buzbee239c4e72012-03-16 08:42:29 -07002005 oatInitGrowableList(cUnit, &cUnit->compilerTemps, 6, kListMisc);
2006 DCHECK_EQ(cUnit->numCompilerTemps, 0);
2007 if (!(cUnit->disableOpt & (1 << kBBOpt))) {
2008 oatDataFlowAnalysisDispatcher(cUnit, basicBlockOpt,
2009 kAllNodes, false /* isIterative */);
2010 }
buzbeee1965672012-03-11 18:39:19 -07002011 }
2012}
2013
buzbee239c4e72012-03-16 08:42:29 -07002014void addLoopHeader(CompilationUnit* cUnit, BasicBlock* header,
2015 BasicBlock* backEdge)
2016{
2017 GrowableListIterator iter;
2018 oatGrowableListIteratorInit(&cUnit->loopHeaders, &iter);
2019 for (LoopInfo* loop = (LoopInfo*)oatGrowableListIteratorNext(&iter);
2020 (loop != NULL); loop = (LoopInfo*)oatGrowableListIteratorNext(&iter)) {
2021 if (loop->header == header) {
2022 oatInsertGrowableList(cUnit, &loop->incomingBackEdges,
2023 (intptr_t)backEdge);
2024 return;
2025 }
2026 }
2027 LoopInfo* info = (LoopInfo*)oatNew(cUnit, sizeof(LoopInfo), true,
2028 kAllocDFInfo);
2029 info->header = header;
2030 oatInitGrowableList(cUnit, &info->incomingBackEdges, 2, kListMisc);
2031 oatInsertGrowableList(cUnit, &info->incomingBackEdges, (intptr_t)backEdge);
2032 oatInsertGrowableList(cUnit, &cUnit->loopHeaders, (intptr_t)info);
2033}
2034
2035bool findBackEdges(struct CompilationUnit* cUnit, struct BasicBlock* bb)
2036{
2037 if ((bb->dataFlowInfo == NULL) || (bb->lastMIRInsn == NULL)) {
2038 return false;
2039 }
2040 Instruction::Code opcode = bb->lastMIRInsn->dalvikInsn.opcode;
2041 if (Instruction::Flags(opcode) & Instruction::kBranch) {
2042 if (bb->taken && (bb->taken->startOffset <= bb->startOffset)) {
2043 DCHECK(bb->dominators != NULL);
2044 if (oatIsBitSet(bb->dominators, bb->taken->id)) {
2045 if (cUnit->printMe) {
2046 LOG(INFO) << "Loop backedge from 0x"
2047 << std::hex << bb->lastMIRInsn->offset
2048 << " to 0x" << std::hex << bb->taken->startOffset;
2049 }
2050 addLoopHeader(cUnit, bb->taken, bb);
2051 }
2052 }
2053 }
2054 return false;
2055}
2056
2057void addBlocksToLoop(CompilationUnit* cUnit, ArenaBitVector* blocks,
2058 BasicBlock* bb, int headId)
2059{
2060 if (!oatIsBitSet(bb->dominators, headId) ||
2061 oatIsBitSet(blocks, bb->id)) {
2062 return;
2063 }
2064 oatSetBit(cUnit, blocks, bb->id);
2065 GrowableListIterator iter;
2066 oatGrowableListIteratorInit(bb->predecessors, &iter);
2067 BasicBlock* predBB;
2068 for (predBB = (BasicBlock*)oatGrowableListIteratorNext(&iter); predBB;
2069 predBB = (BasicBlock*)oatGrowableListIteratorNext(&iter)) {
2070 addBlocksToLoop(cUnit, blocks, predBB, headId);
2071 }
2072}
2073
2074void oatDumpLoops(CompilationUnit *cUnit)
2075{
2076 GrowableListIterator iter;
2077 oatGrowableListIteratorInit(&cUnit->loopHeaders, &iter);
2078 for (LoopInfo* loop = (LoopInfo*)oatGrowableListIteratorNext(&iter);
2079 (loop != NULL); loop = (LoopInfo*)oatGrowableListIteratorNext(&iter)) {
2080 LOG(INFO) << "Loop head block id " << loop->header->id
2081 << ", offset 0x" << std::hex << loop->header->startOffset
2082 << ", Depth: " << loop->header->nestingDepth;
2083 GrowableListIterator iter;
2084 oatGrowableListIteratorInit(&loop->incomingBackEdges, &iter);
2085 BasicBlock* edgeBB;
2086 for (edgeBB = (BasicBlock*)oatGrowableListIteratorNext(&iter); edgeBB;
2087 edgeBB = (BasicBlock*)oatGrowableListIteratorNext(&iter)) {
2088 LOG(INFO) << " Backedge block id " << edgeBB->id
2089 << ", offset 0x" << std::hex << edgeBB->startOffset;
2090 ArenaBitVectorIterator bIter;
2091 oatBitVectorIteratorInit(loop->blocks, &bIter);
2092 for (int bbId = oatBitVectorIteratorNext(&bIter); bbId != -1;
2093 bbId = oatBitVectorIteratorNext(&bIter)) {
2094 BasicBlock *bb;
2095 bb = (BasicBlock*)
2096 oatGrowableListGetElement(&cUnit->blockList, bbId);
2097 LOG(INFO) << " (" << bb->id << ", 0x" << std::hex
2098 << bb->startOffset << ")";
2099 }
2100 }
2101 }
2102}
2103
2104void oatMethodLoopDetection(CompilationUnit *cUnit)
2105{
2106 if (cUnit->disableOpt & (1 << kPromoteRegs)) {
2107 return;
2108 }
2109 oatInitGrowableList(cUnit, &cUnit->loopHeaders, 6, kListMisc);
2110 // Find the loop headers
2111 oatDataFlowAnalysisDispatcher(cUnit, findBackEdges,
2112 kAllNodes, false /* isIterative */);
2113 GrowableListIterator iter;
2114 oatGrowableListIteratorInit(&cUnit->loopHeaders, &iter);
2115 // Add blocks to each header
2116 for (LoopInfo* loop = (LoopInfo*)oatGrowableListIteratorNext(&iter);
2117 loop; loop = (LoopInfo*)oatGrowableListIteratorNext(&iter)) {
2118 loop->blocks = oatAllocBitVector(cUnit, cUnit->numBlocks, true,
2119 kBitMapMisc);
2120 oatSetBit(cUnit, loop->blocks, loop->header->id);
2121 GrowableListIterator iter;
2122 oatGrowableListIteratorInit(&loop->incomingBackEdges, &iter);
2123 BasicBlock* edgeBB;
2124 for (edgeBB = (BasicBlock*)oatGrowableListIteratorNext(&iter); edgeBB;
2125 edgeBB = (BasicBlock*)oatGrowableListIteratorNext(&iter)) {
2126 addBlocksToLoop(cUnit, loop->blocks, edgeBB, loop->header->id);
2127 }
2128 }
2129 // Compute the nesting depth of each header
2130 oatGrowableListIteratorInit(&cUnit->loopHeaders, &iter);
2131 for (LoopInfo* loop = (LoopInfo*)oatGrowableListIteratorNext(&iter);
2132 loop; loop = (LoopInfo*)oatGrowableListIteratorNext(&iter)) {
2133 GrowableListIterator iter2;
2134 oatGrowableListIteratorInit(&cUnit->loopHeaders, &iter2);
2135 LoopInfo* loop2;
2136 for (loop2 = (LoopInfo*)oatGrowableListIteratorNext(&iter2);
2137 loop2; loop2 = (LoopInfo*)oatGrowableListIteratorNext(&iter2)) {
2138 if (oatIsBitSet(loop2->blocks, loop->header->id)) {
2139 loop->header->nestingDepth++;
2140 }
2141 }
2142 }
2143 // Assign nesting depth to each block in all loops
2144 oatGrowableListIteratorInit(&cUnit->loopHeaders, &iter);
2145 for (LoopInfo* loop = (LoopInfo*)oatGrowableListIteratorNext(&iter);
2146 (loop != NULL); loop = (LoopInfo*)oatGrowableListIteratorNext(&iter)) {
2147 ArenaBitVectorIterator bIter;
2148 oatBitVectorIteratorInit(loop->blocks, &bIter);
2149 for (int bbId = oatBitVectorIteratorNext(&bIter); bbId != -1;
2150 bbId = oatBitVectorIteratorNext(&bIter)) {
2151 BasicBlock *bb;
2152 bb = (BasicBlock*) oatGrowableListGetElement(&cUnit->blockList,
2153 bbId);
2154 bb->nestingDepth = std::max(bb->nestingDepth,
2155 loop->header->nestingDepth);
2156 }
2157 }
2158 if (cUnit->printMe) {
2159 oatDumpLoops(cUnit);
2160 }
2161}
2162
2163/*
buzbee9c044ce2012-03-18 13:24:07 -07002164 * This function will make a best guess at whether the invoke will
2165 * end up using Method*. It isn't critical to get it exactly right,
2166 * and attempting to do would involve more complexity than it's
2167 * worth.
2168 */
2169bool invokeUsesMethodStar(CompilationUnit* cUnit, MIR* mir)
2170{
2171 InvokeType type;
2172 Instruction::Code opcode = mir->dalvikInsn.opcode;
Elliott Hughesb25c3f62012-03-26 16:35:06 -07002173 switch (opcode) {
buzbee9c044ce2012-03-18 13:24:07 -07002174 case Instruction::INVOKE_STATIC:
2175 case Instruction::INVOKE_STATIC_RANGE:
2176 type = kStatic;
2177 break;
2178 case Instruction::INVOKE_DIRECT:
2179 case Instruction::INVOKE_DIRECT_RANGE:
2180 type = kDirect;
2181 break;
2182 case Instruction::INVOKE_VIRTUAL:
2183 case Instruction::INVOKE_VIRTUAL_RANGE:
2184 type = kVirtual;
2185 break;
2186 case Instruction::INVOKE_INTERFACE:
2187 case Instruction::INVOKE_INTERFACE_RANGE:
2188 return false;
2189 case Instruction::INVOKE_SUPER_RANGE:
2190 case Instruction::INVOKE_SUPER:
2191 type = kSuper;
2192 break;
2193 default:
2194 LOG(WARNING) << "Unexpected invoke op: " << (int)opcode;
2195 return false;
2196 }
2197 OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
2198 *cUnit->dex_file, *cUnit->dex_cache,
2199 cUnit->code_item, cUnit->method_idx,
2200 cUnit->access_flags);
2201 // TODO: add a flag so we don't counts the stats for this twice
2202 uint32_t dexMethodIdx = mir->dalvikInsn.vB;
2203 int vtableIdx;
2204 uintptr_t directCode;
2205 uintptr_t directMethod;
2206 bool fastPath =
2207 cUnit->compiler->ComputeInvokeInfo(dexMethodIdx, &mUnit, type,
2208 vtableIdx, directCode,
2209 directMethod) &&
2210 !SLOW_INVOKE_PATH;
2211 return (((type == kDirect) || (type == kStatic)) &&
2212 fastPath && ((directCode == 0) || (directMethod == 0)));
2213}
2214
2215/*
buzbee239c4e72012-03-16 08:42:29 -07002216 * Count uses, weighting by loop nesting depth. This code only
2217 * counts explicitly used sRegs. A later phase will add implicit
2218 * counts for things such as Method*, null-checked references, etc.
2219 */
2220bool countUses(struct CompilationUnit* cUnit, struct BasicBlock* bb)
2221{
2222 if (bb->blockType != kDalvikByteCode) {
2223 return false;
2224 }
2225 for (MIR* mir = bb->firstMIRInsn; (mir != NULL); mir = mir->next) {
2226 if (mir->ssaRep == NULL) {
2227 continue;
2228 }
buzbee9c044ce2012-03-18 13:24:07 -07002229 uint32_t weight = std::min(16U, (uint32_t)bb->nestingDepth);
buzbee239c4e72012-03-16 08:42:29 -07002230 for (int i = 0; i < mir->ssaRep->numUses; i++) {
2231 int sReg = mir->ssaRep->uses[i];
buzbee239c4e72012-03-16 08:42:29 -07002232 DCHECK_LT(sReg, (int)cUnit->useCounts.numUsed);
2233 cUnit->useCounts.elemList[sReg] += (1 << weight);
2234 }
buzbee9c044ce2012-03-18 13:24:07 -07002235 if (!(cUnit->disableOpt & (1 << kPromoteCompilerTemps))) {
2236 int dfAttributes = oatDataFlowAttributes[mir->dalvikInsn.opcode];
2237 // Implicit use of Method* ? */
2238 if (dfAttributes & DF_UMS) {
2239 /*
2240 * Some invokes will not use Method* - need to perform test similar
2241 * to that found in genInvoke() to decide whether to count refs
2242 * for Method* on invoke-class opcodes.
2243 * TODO: refactor for common test here, save results for genInvoke
2244 */
2245 int usesMethodStar = true;
2246 if ((dfAttributes & (DF_FORMAT_35C | DF_FORMAT_3RC)) &&
2247 !(dfAttributes & DF_NON_NULL_RET)) {
2248 usesMethodStar &= invokeUsesMethodStar(cUnit, mir);
2249 }
2250 if (usesMethodStar) {
2251 cUnit->useCounts.elemList[cUnit->methodSReg] += (1 << weight);
2252 }
2253 }
2254 }
buzbee239c4e72012-03-16 08:42:29 -07002255 }
2256 return false;
2257}
2258
2259void oatMethodUseCount(CompilationUnit *cUnit)
2260{
2261 if (cUnit->disableOpt & (1 << kPromoteRegs)) {
2262 return;
2263 }
2264 oatInitGrowableList(cUnit, &cUnit->useCounts, cUnit->numSSARegs + 32,
2265 kListMisc);
2266 // Initialize list
2267 for (int i = 0; i < cUnit->numSSARegs; i++) {
2268 oatInsertGrowableList(cUnit, &cUnit->useCounts, 0);
2269 }
2270 oatDataFlowAnalysisDispatcher(cUnit, countUses,
2271 kAllNodes, false /* isIterative */);
2272}
2273
Elliott Hughes11d1b0c2012-01-23 16:57:47 -08002274} // namespace art