The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2008 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 | */ |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 16 | |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 17 | /* |
| 18 | * Dalvik instruction utility functions. |
Dan Bornstein | 8424432 | 2010-11-17 12:05:04 -0800 | [diff] [blame] | 19 | * |
| 20 | * IMPORTANT NOTE: Much of the contents of this file are generated |
| 21 | * automatically by the opcode-gen tool. Any edits to the generated |
| 22 | * sections will get wiped out the next time the tool is run. |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 23 | */ |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 24 | |
Dan Bornstein | 8424432 | 2010-11-17 12:05:04 -0800 | [diff] [blame] | 25 | #include "InstrUtils.h" |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 26 | #include <stdlib.h> |
| 27 | |
Dan Bornstein | 8424432 | 2010-11-17 12:05:04 -0800 | [diff] [blame] | 28 | /* |
| 29 | * Table that maps each opcode to the full width of instructions that |
| 30 | * use that opcode, in (16-bit) code units. Unimplemented opcodes as |
| 31 | * well as the "breakpoint" opcode have a width of zero. |
| 32 | */ |
Dan Bornstein | ccaab18 | 2010-12-03 15:32:40 -0800 | [diff] [blame] | 33 | static InstructionWidth gInstructionWidthTable[kNumPackedOpcodes] = { |
Dan Bornstein | 8424432 | 2010-11-17 12:05:04 -0800 | [diff] [blame] | 34 | // BEGIN(libdex-widths); GENERATED AUTOMATICALLY BY opcode-gen |
| 35 | 1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 1, 1, 1, 1, |
| 36 | 1, 1, 1, 2, 3, 2, 2, 3, 5, 2, 2, 3, 2, 1, 1, 2, |
| 37 | 2, 1, 2, 2, 3, 3, 3, 1, 1, 2, 3, 3, 3, 2, 2, 2, |
| 38 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, |
| 39 | 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
| 40 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
| 41 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, |
| 42 | 3, 3, 3, 0, 3, 3, 3, 3, 3, 0, 0, 1, 1, 1, 1, 1, |
| 43 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
| 44 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
| 45 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
| 46 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
| 47 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
| 48 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
| 49 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 3, 3, |
| 50 | 3, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 0, |
| 51 | // END(libdex-widths) |
| 52 | }; |
| 53 | |
| 54 | /* |
| 55 | * Table that maps each opcode to the flags associated with that |
| 56 | * opcode. |
| 57 | */ |
Dan Bornstein | ccaab18 | 2010-12-03 15:32:40 -0800 | [diff] [blame] | 58 | static u1 gOpcodeFlagsTable[kNumPackedOpcodes] = { |
Dan Bornstein | 8424432 | 2010-11-17 12:05:04 -0800 | [diff] [blame] | 59 | // BEGIN(libdex-flags); GENERATED AUTOMATICALLY BY opcode-gen |
| 60 | kInstrCanContinue, |
| 61 | kInstrCanContinue, |
| 62 | kInstrCanContinue, |
| 63 | kInstrCanContinue, |
| 64 | kInstrCanContinue, |
| 65 | kInstrCanContinue, |
| 66 | kInstrCanContinue, |
| 67 | kInstrCanContinue, |
| 68 | kInstrCanContinue, |
| 69 | kInstrCanContinue, |
| 70 | kInstrCanContinue, |
| 71 | kInstrCanContinue, |
| 72 | kInstrCanContinue, |
| 73 | kInstrCanContinue, |
| 74 | kInstrCanReturn, |
| 75 | kInstrCanReturn, |
| 76 | kInstrCanReturn, |
| 77 | kInstrCanReturn, |
| 78 | kInstrCanContinue, |
| 79 | kInstrCanContinue, |
| 80 | kInstrCanContinue, |
| 81 | kInstrCanContinue, |
| 82 | kInstrCanContinue, |
| 83 | kInstrCanContinue, |
| 84 | kInstrCanContinue, |
| 85 | kInstrCanContinue, |
| 86 | kInstrCanContinue|kInstrCanThrow, |
| 87 | kInstrCanContinue|kInstrCanThrow, |
| 88 | kInstrCanContinue|kInstrCanThrow, |
| 89 | kInstrCanContinue|kInstrCanThrow, |
| 90 | kInstrCanContinue|kInstrCanThrow, |
| 91 | kInstrCanContinue|kInstrCanThrow, |
| 92 | kInstrCanContinue|kInstrCanThrow, |
| 93 | kInstrCanContinue|kInstrCanThrow, |
| 94 | kInstrCanContinue|kInstrCanThrow, |
| 95 | kInstrCanContinue|kInstrCanThrow, |
| 96 | kInstrCanContinue|kInstrCanThrow, |
| 97 | kInstrCanContinue|kInstrCanThrow, |
| 98 | kInstrCanContinue, |
| 99 | kInstrCanThrow, |
| 100 | kInstrCanBranch, |
| 101 | kInstrCanBranch, |
| 102 | kInstrCanBranch, |
| 103 | kInstrCanContinue|kInstrCanSwitch, |
| 104 | kInstrCanContinue|kInstrCanSwitch, |
| 105 | kInstrCanContinue, |
| 106 | kInstrCanContinue, |
| 107 | kInstrCanContinue, |
| 108 | kInstrCanContinue, |
| 109 | kInstrCanContinue, |
| 110 | kInstrCanContinue|kInstrCanBranch, |
| 111 | kInstrCanContinue|kInstrCanBranch, |
| 112 | kInstrCanContinue|kInstrCanBranch, |
| 113 | kInstrCanContinue|kInstrCanBranch, |
| 114 | kInstrCanContinue|kInstrCanBranch, |
| 115 | kInstrCanContinue|kInstrCanBranch, |
| 116 | kInstrCanContinue|kInstrCanBranch, |
| 117 | kInstrCanContinue|kInstrCanBranch, |
| 118 | kInstrCanContinue|kInstrCanBranch, |
| 119 | kInstrCanContinue|kInstrCanBranch, |
| 120 | kInstrCanContinue|kInstrCanBranch, |
| 121 | kInstrCanContinue|kInstrCanBranch, |
| 122 | 0, |
| 123 | 0, |
| 124 | 0, |
| 125 | 0, |
| 126 | 0, |
| 127 | 0, |
| 128 | kInstrCanContinue|kInstrCanThrow, |
| 129 | kInstrCanContinue|kInstrCanThrow, |
| 130 | kInstrCanContinue|kInstrCanThrow, |
| 131 | kInstrCanContinue|kInstrCanThrow, |
| 132 | kInstrCanContinue|kInstrCanThrow, |
| 133 | kInstrCanContinue|kInstrCanThrow, |
| 134 | kInstrCanContinue|kInstrCanThrow, |
| 135 | kInstrCanContinue|kInstrCanThrow, |
| 136 | kInstrCanContinue|kInstrCanThrow, |
| 137 | kInstrCanContinue|kInstrCanThrow, |
| 138 | kInstrCanContinue|kInstrCanThrow, |
| 139 | kInstrCanContinue|kInstrCanThrow, |
| 140 | kInstrCanContinue|kInstrCanThrow, |
| 141 | kInstrCanContinue|kInstrCanThrow, |
| 142 | kInstrCanContinue|kInstrCanThrow, |
| 143 | kInstrCanContinue|kInstrCanThrow, |
| 144 | kInstrCanContinue|kInstrCanThrow, |
| 145 | kInstrCanContinue|kInstrCanThrow, |
| 146 | kInstrCanContinue|kInstrCanThrow, |
| 147 | kInstrCanContinue|kInstrCanThrow, |
| 148 | kInstrCanContinue|kInstrCanThrow, |
| 149 | kInstrCanContinue|kInstrCanThrow, |
| 150 | kInstrCanContinue|kInstrCanThrow, |
| 151 | kInstrCanContinue|kInstrCanThrow, |
| 152 | kInstrCanContinue|kInstrCanThrow, |
| 153 | kInstrCanContinue|kInstrCanThrow, |
| 154 | kInstrCanContinue|kInstrCanThrow, |
| 155 | kInstrCanContinue|kInstrCanThrow, |
| 156 | kInstrCanContinue|kInstrCanThrow, |
| 157 | kInstrCanContinue|kInstrCanThrow, |
| 158 | kInstrCanContinue|kInstrCanThrow, |
| 159 | kInstrCanContinue|kInstrCanThrow, |
| 160 | kInstrCanContinue|kInstrCanThrow, |
| 161 | kInstrCanContinue|kInstrCanThrow, |
| 162 | kInstrCanContinue|kInstrCanThrow, |
| 163 | kInstrCanContinue|kInstrCanThrow, |
| 164 | kInstrCanContinue|kInstrCanThrow, |
| 165 | kInstrCanContinue|kInstrCanThrow, |
| 166 | kInstrCanContinue|kInstrCanThrow, |
| 167 | kInstrCanContinue|kInstrCanThrow, |
| 168 | kInstrCanContinue|kInstrCanThrow, |
| 169 | kInstrCanContinue|kInstrCanThrow, |
| 170 | kInstrCanContinue|kInstrCanThrow|kInstrInvoke, |
| 171 | kInstrCanContinue|kInstrCanThrow|kInstrInvoke, |
| 172 | kInstrCanContinue|kInstrCanThrow|kInstrInvoke, |
| 173 | kInstrCanContinue|kInstrCanThrow|kInstrInvoke, |
| 174 | kInstrCanContinue|kInstrCanThrow|kInstrInvoke, |
| 175 | 0, |
| 176 | kInstrCanContinue|kInstrCanThrow|kInstrInvoke, |
| 177 | kInstrCanContinue|kInstrCanThrow|kInstrInvoke, |
| 178 | kInstrCanContinue|kInstrCanThrow|kInstrInvoke, |
| 179 | kInstrCanContinue|kInstrCanThrow|kInstrInvoke, |
| 180 | kInstrCanContinue|kInstrCanThrow|kInstrInvoke, |
| 181 | 0, |
| 182 | 0, |
| 183 | kInstrCanContinue, |
| 184 | kInstrCanContinue, |
| 185 | kInstrCanContinue, |
| 186 | kInstrCanContinue, |
| 187 | kInstrCanContinue, |
| 188 | kInstrCanContinue, |
| 189 | kInstrCanContinue, |
| 190 | kInstrCanContinue, |
| 191 | kInstrCanContinue, |
| 192 | kInstrCanContinue, |
| 193 | kInstrCanContinue, |
| 194 | kInstrCanContinue, |
| 195 | kInstrCanContinue, |
| 196 | kInstrCanContinue, |
| 197 | kInstrCanContinue, |
| 198 | kInstrCanContinue, |
| 199 | kInstrCanContinue, |
| 200 | kInstrCanContinue, |
| 201 | kInstrCanContinue, |
| 202 | kInstrCanContinue, |
| 203 | kInstrCanContinue, |
| 204 | kInstrCanContinue, |
| 205 | kInstrCanContinue, |
| 206 | kInstrCanContinue, |
| 207 | kInstrCanContinue|kInstrCanThrow, |
| 208 | kInstrCanContinue|kInstrCanThrow, |
| 209 | kInstrCanContinue, |
| 210 | kInstrCanContinue, |
| 211 | kInstrCanContinue, |
| 212 | kInstrCanContinue, |
| 213 | kInstrCanContinue, |
| 214 | kInstrCanContinue, |
| 215 | kInstrCanContinue, |
| 216 | kInstrCanContinue, |
| 217 | kInstrCanContinue, |
| 218 | kInstrCanContinue|kInstrCanThrow, |
| 219 | kInstrCanContinue|kInstrCanThrow, |
| 220 | kInstrCanContinue, |
| 221 | kInstrCanContinue, |
| 222 | kInstrCanContinue, |
| 223 | kInstrCanContinue, |
| 224 | kInstrCanContinue, |
| 225 | kInstrCanContinue, |
| 226 | kInstrCanContinue, |
| 227 | kInstrCanContinue, |
| 228 | kInstrCanContinue, |
| 229 | kInstrCanContinue, |
| 230 | kInstrCanContinue, |
| 231 | kInstrCanContinue, |
| 232 | kInstrCanContinue, |
| 233 | kInstrCanContinue, |
| 234 | kInstrCanContinue, |
| 235 | kInstrCanContinue, |
| 236 | kInstrCanContinue, |
| 237 | kInstrCanContinue, |
| 238 | kInstrCanContinue, |
| 239 | kInstrCanContinue|kInstrCanThrow, |
| 240 | kInstrCanContinue|kInstrCanThrow, |
| 241 | kInstrCanContinue, |
| 242 | kInstrCanContinue, |
| 243 | kInstrCanContinue, |
| 244 | kInstrCanContinue, |
| 245 | kInstrCanContinue, |
| 246 | kInstrCanContinue, |
| 247 | kInstrCanContinue, |
| 248 | kInstrCanContinue, |
| 249 | kInstrCanContinue, |
| 250 | kInstrCanContinue|kInstrCanThrow, |
| 251 | kInstrCanContinue|kInstrCanThrow, |
| 252 | kInstrCanContinue, |
| 253 | kInstrCanContinue, |
| 254 | kInstrCanContinue, |
| 255 | kInstrCanContinue, |
| 256 | kInstrCanContinue, |
| 257 | kInstrCanContinue, |
| 258 | kInstrCanContinue, |
| 259 | kInstrCanContinue, |
| 260 | kInstrCanContinue, |
| 261 | kInstrCanContinue, |
| 262 | kInstrCanContinue, |
| 263 | kInstrCanContinue, |
| 264 | kInstrCanContinue, |
| 265 | kInstrCanContinue, |
| 266 | kInstrCanContinue, |
| 267 | kInstrCanContinue, |
| 268 | kInstrCanContinue, |
| 269 | kInstrCanContinue, |
| 270 | kInstrCanContinue, |
| 271 | kInstrCanContinue|kInstrCanThrow, |
| 272 | kInstrCanContinue|kInstrCanThrow, |
| 273 | kInstrCanContinue, |
| 274 | kInstrCanContinue, |
| 275 | kInstrCanContinue, |
| 276 | kInstrCanContinue, |
| 277 | kInstrCanContinue, |
| 278 | kInstrCanContinue, |
| 279 | kInstrCanContinue|kInstrCanThrow, |
| 280 | kInstrCanContinue|kInstrCanThrow, |
| 281 | kInstrCanContinue, |
| 282 | kInstrCanContinue, |
| 283 | kInstrCanContinue, |
| 284 | kInstrCanContinue, |
| 285 | kInstrCanContinue, |
| 286 | kInstrCanContinue, |
| 287 | kInstrCanContinue|kInstrCanThrow, |
| 288 | kInstrCanContinue|kInstrCanThrow, |
| 289 | kInstrCanContinue|kInstrCanThrow, |
| 290 | kInstrCanContinue|kInstrCanThrow, |
| 291 | kInstrCanContinue|kInstrCanThrow, |
| 292 | kInstrCanContinue|kInstrCanThrow, |
| 293 | kInstrCanContinue|kInstrCanThrow, |
| 294 | kInstrCanContinue|kInstrCanThrow, |
| 295 | kInstrCanContinue|kInstrCanThrow, |
| 296 | 0, |
| 297 | kInstrCanThrow, |
| 298 | kInstrCanContinue|kInstrCanThrow, |
| 299 | kInstrCanContinue|kInstrCanThrow, |
Carl Shapiro | 3475f9c | 2011-03-21 13:35:24 -0700 | [diff] [blame] | 300 | kInstrCanContinue|kInstrCanThrow|kInstrInvoke, |
Dan Bornstein | 8424432 | 2010-11-17 12:05:04 -0800 | [diff] [blame] | 301 | kInstrCanReturn, |
| 302 | kInstrCanContinue|kInstrCanThrow, |
| 303 | kInstrCanContinue|kInstrCanThrow, |
| 304 | kInstrCanContinue|kInstrCanThrow, |
| 305 | kInstrCanContinue|kInstrCanThrow, |
| 306 | kInstrCanContinue|kInstrCanThrow, |
| 307 | kInstrCanContinue|kInstrCanThrow, |
| 308 | kInstrCanContinue|kInstrCanThrow|kInstrInvoke, |
| 309 | kInstrCanContinue|kInstrCanThrow|kInstrInvoke, |
| 310 | kInstrCanContinue|kInstrCanThrow|kInstrInvoke, |
| 311 | kInstrCanContinue|kInstrCanThrow|kInstrInvoke, |
| 312 | kInstrCanContinue|kInstrCanThrow, |
| 313 | kInstrCanContinue|kInstrCanThrow, |
| 314 | kInstrCanContinue|kInstrCanThrow, |
| 315 | 0, |
| 316 | // END(libdex-flags) |
| 317 | }; |
| 318 | |
| 319 | /* |
| 320 | * Table that maps each opcode to the instruction format associated |
| 321 | * that opcode. |
| 322 | */ |
Dan Bornstein | ccaab18 | 2010-12-03 15:32:40 -0800 | [diff] [blame] | 323 | static u1 gInstructionFormatTable[kNumPackedOpcodes] = { |
Dan Bornstein | 8424432 | 2010-11-17 12:05:04 -0800 | [diff] [blame] | 324 | // BEGIN(libdex-formats); GENERATED AUTOMATICALLY BY opcode-gen |
| 325 | kFmt10x, kFmt12x, kFmt22x, kFmt32x, kFmt12x, kFmt22x, kFmt32x, |
| 326 | kFmt12x, kFmt22x, kFmt32x, kFmt11x, kFmt11x, kFmt11x, kFmt11x, |
| 327 | kFmt10x, kFmt11x, kFmt11x, kFmt11x, kFmt11n, kFmt21s, kFmt31i, |
| 328 | kFmt21h, kFmt21s, kFmt31i, kFmt51l, kFmt21h, kFmt21c, kFmt31c, |
| 329 | kFmt21c, kFmt11x, kFmt11x, kFmt21c, kFmt22c, kFmt12x, kFmt21c, |
| 330 | kFmt22c, kFmt35c, kFmt3rc, kFmt31t, kFmt11x, kFmt10t, kFmt20t, |
| 331 | kFmt30t, kFmt31t, kFmt31t, kFmt23x, kFmt23x, kFmt23x, kFmt23x, |
| 332 | kFmt23x, kFmt22t, kFmt22t, kFmt22t, kFmt22t, kFmt22t, kFmt22t, |
| 333 | kFmt21t, kFmt21t, kFmt21t, kFmt21t, kFmt21t, kFmt21t, kFmt00x, |
| 334 | kFmt00x, kFmt00x, kFmt00x, kFmt00x, kFmt00x, kFmt23x, kFmt23x, |
| 335 | kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, |
| 336 | kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt22c, kFmt22c, |
| 337 | kFmt22c, kFmt22c, kFmt22c, kFmt22c, kFmt22c, kFmt22c, kFmt22c, |
| 338 | kFmt22c, kFmt22c, kFmt22c, kFmt22c, kFmt22c, kFmt21c, kFmt21c, |
| 339 | kFmt21c, kFmt21c, kFmt21c, kFmt21c, kFmt21c, kFmt21c, kFmt21c, |
| 340 | kFmt21c, kFmt21c, kFmt21c, kFmt21c, kFmt21c, kFmt35c, kFmt35c, |
| 341 | kFmt35c, kFmt35c, kFmt35c, kFmt00x, kFmt3rc, kFmt3rc, kFmt3rc, |
| 342 | kFmt3rc, kFmt3rc, kFmt00x, kFmt00x, kFmt12x, kFmt12x, kFmt12x, |
| 343 | kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, |
| 344 | kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, |
| 345 | kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt23x, kFmt23x, kFmt23x, |
| 346 | kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, |
| 347 | kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, |
| 348 | kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, |
| 349 | kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, |
| 350 | kFmt23x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, |
| 351 | kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, |
| 352 | kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, |
| 353 | kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, |
| 354 | kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt22s, kFmt22s, |
| 355 | kFmt22s, kFmt22s, kFmt22s, kFmt22s, kFmt22s, kFmt22s, kFmt22b, |
| 356 | kFmt22b, kFmt22b, kFmt22b, kFmt22b, kFmt22b, kFmt22b, kFmt22b, |
| 357 | kFmt22b, kFmt22b, kFmt22b, kFmt22c, kFmt22c, kFmt21c, kFmt21c, |
| 358 | kFmt22c, kFmt22c, kFmt22c, kFmt21c, kFmt21c, kFmt00x, kFmt20bc, |
| 359 | kFmt35mi, kFmt3rmi, kFmt35c, kFmt10x, kFmt22cs, kFmt22cs, kFmt22cs, |
| 360 | kFmt22cs, kFmt22cs, kFmt22cs, kFmt35ms, kFmt3rms, kFmt35ms, kFmt3rms, |
Elliott Hughes | ab35b50 | 2012-01-04 15:38:58 -0800 | [diff] [blame] | 361 | kFmt22c, kFmt21c, kFmt21c, kFmt00x, |
Dan Bornstein | 8424432 | 2010-11-17 12:05:04 -0800 | [diff] [blame] | 362 | // END(libdex-formats) |
| 363 | }; |
| 364 | |
| 365 | /* |
| 366 | * Table that maps each opcode to the index type implied by that |
| 367 | * opcode. |
| 368 | */ |
Dan Bornstein | ccaab18 | 2010-12-03 15:32:40 -0800 | [diff] [blame] | 369 | static u1 gInstructionIndexTypeTable[kNumPackedOpcodes] = { |
Dan Bornstein | 8424432 | 2010-11-17 12:05:04 -0800 | [diff] [blame] | 370 | // BEGIN(libdex-index-types); GENERATED AUTOMATICALLY BY opcode-gen |
| 371 | kIndexNone, kIndexNone, kIndexNone, |
| 372 | kIndexNone, kIndexNone, kIndexNone, |
| 373 | kIndexNone, kIndexNone, kIndexNone, |
| 374 | kIndexNone, kIndexNone, kIndexNone, |
| 375 | kIndexNone, kIndexNone, kIndexNone, |
| 376 | kIndexNone, kIndexNone, kIndexNone, |
| 377 | kIndexNone, kIndexNone, kIndexNone, |
| 378 | kIndexNone, kIndexNone, kIndexNone, |
| 379 | kIndexNone, kIndexNone, kIndexStringRef, |
| 380 | kIndexStringRef, kIndexTypeRef, kIndexNone, |
| 381 | kIndexNone, kIndexTypeRef, kIndexTypeRef, |
| 382 | kIndexNone, kIndexTypeRef, kIndexTypeRef, |
| 383 | kIndexTypeRef, kIndexTypeRef, kIndexNone, |
| 384 | kIndexNone, kIndexNone, kIndexNone, |
| 385 | kIndexNone, kIndexNone, kIndexNone, |
| 386 | kIndexNone, kIndexNone, kIndexNone, |
| 387 | kIndexNone, kIndexNone, kIndexNone, |
| 388 | kIndexNone, kIndexNone, kIndexNone, |
| 389 | kIndexNone, kIndexNone, kIndexNone, |
| 390 | kIndexNone, kIndexNone, kIndexNone, |
| 391 | kIndexNone, kIndexNone, kIndexUnknown, |
| 392 | kIndexUnknown, kIndexUnknown, kIndexUnknown, |
| 393 | kIndexUnknown, kIndexUnknown, kIndexNone, |
| 394 | kIndexNone, kIndexNone, kIndexNone, |
| 395 | kIndexNone, kIndexNone, kIndexNone, |
| 396 | kIndexNone, kIndexNone, kIndexNone, |
| 397 | kIndexNone, kIndexNone, kIndexNone, |
| 398 | kIndexNone, kIndexFieldRef, kIndexFieldRef, |
| 399 | kIndexFieldRef, kIndexFieldRef, kIndexFieldRef, |
| 400 | kIndexFieldRef, kIndexFieldRef, kIndexFieldRef, |
| 401 | kIndexFieldRef, kIndexFieldRef, kIndexFieldRef, |
| 402 | kIndexFieldRef, kIndexFieldRef, kIndexFieldRef, |
| 403 | kIndexFieldRef, kIndexFieldRef, kIndexFieldRef, |
| 404 | kIndexFieldRef, kIndexFieldRef, kIndexFieldRef, |
| 405 | kIndexFieldRef, kIndexFieldRef, kIndexFieldRef, |
| 406 | kIndexFieldRef, kIndexFieldRef, kIndexFieldRef, |
| 407 | kIndexFieldRef, kIndexFieldRef, kIndexMethodRef, |
| 408 | kIndexMethodRef, kIndexMethodRef, kIndexMethodRef, |
| 409 | kIndexMethodRef, kIndexUnknown, kIndexMethodRef, |
| 410 | kIndexMethodRef, kIndexMethodRef, kIndexMethodRef, |
| 411 | kIndexMethodRef, kIndexUnknown, kIndexUnknown, |
| 412 | kIndexNone, kIndexNone, kIndexNone, |
| 413 | kIndexNone, kIndexNone, kIndexNone, |
| 414 | kIndexNone, kIndexNone, kIndexNone, |
| 415 | kIndexNone, kIndexNone, kIndexNone, |
| 416 | kIndexNone, kIndexNone, kIndexNone, |
| 417 | kIndexNone, kIndexNone, kIndexNone, |
| 418 | kIndexNone, kIndexNone, kIndexNone, |
| 419 | kIndexNone, kIndexNone, kIndexNone, |
| 420 | kIndexNone, kIndexNone, kIndexNone, |
| 421 | kIndexNone, kIndexNone, kIndexNone, |
| 422 | kIndexNone, kIndexNone, kIndexNone, |
| 423 | kIndexNone, kIndexNone, kIndexNone, |
| 424 | kIndexNone, kIndexNone, kIndexNone, |
| 425 | kIndexNone, kIndexNone, kIndexNone, |
| 426 | kIndexNone, kIndexNone, kIndexNone, |
| 427 | kIndexNone, kIndexNone, kIndexNone, |
| 428 | kIndexNone, kIndexNone, kIndexNone, |
| 429 | kIndexNone, kIndexNone, kIndexNone, |
| 430 | kIndexNone, kIndexNone, kIndexNone, |
| 431 | kIndexNone, kIndexNone, kIndexNone, |
| 432 | kIndexNone, kIndexNone, kIndexNone, |
| 433 | kIndexNone, kIndexNone, kIndexNone, |
| 434 | kIndexNone, kIndexNone, kIndexNone, |
| 435 | kIndexNone, kIndexNone, kIndexNone, |
| 436 | kIndexNone, kIndexNone, kIndexNone, |
| 437 | kIndexNone, kIndexNone, kIndexNone, |
| 438 | kIndexNone, kIndexNone, kIndexNone, |
| 439 | kIndexNone, kIndexNone, kIndexNone, |
| 440 | kIndexNone, kIndexNone, kIndexNone, |
| 441 | kIndexNone, kIndexNone, kIndexNone, |
| 442 | kIndexNone, kIndexNone, kIndexNone, |
| 443 | kIndexNone, kIndexNone, kIndexNone, |
| 444 | kIndexNone, kIndexNone, kIndexNone, |
| 445 | kIndexNone, kIndexNone, kIndexNone, |
| 446 | kIndexNone, kIndexNone, kIndexFieldRef, |
| 447 | kIndexFieldRef, kIndexFieldRef, kIndexFieldRef, |
| 448 | kIndexFieldRef, kIndexFieldRef, kIndexFieldRef, |
| 449 | kIndexFieldRef, kIndexFieldRef, kIndexUnknown, |
| 450 | kIndexVaries, kIndexInlineMethod, kIndexInlineMethod, |
| 451 | kIndexMethodRef, kIndexNone, kIndexFieldOffset, |
| 452 | kIndexFieldOffset, kIndexFieldOffset, kIndexFieldOffset, |
| 453 | kIndexFieldOffset, kIndexFieldOffset, kIndexVtableOffset, |
| 454 | kIndexVtableOffset, kIndexVtableOffset, kIndexVtableOffset, |
| 455 | kIndexFieldRef, kIndexFieldRef, kIndexFieldRef, |
Elliott Hughes | ab35b50 | 2012-01-04 15:38:58 -0800 | [diff] [blame] | 456 | kIndexUnknown, |
Dan Bornstein | 8424432 | 2010-11-17 12:05:04 -0800 | [diff] [blame] | 457 | // END(libdex-index-types) |
| 458 | }; |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 459 | |
| 460 | /* |
Dan Bornstein | 5432239 | 2010-11-17 14:16:56 -0800 | [diff] [blame] | 461 | * Global InstructionInfoTables struct. |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 462 | */ |
Dan Bornstein | 5432239 | 2010-11-17 14:16:56 -0800 | [diff] [blame] | 463 | InstructionInfoTables gDexOpcodeInfo = { |
Dan Bornstein | e485276 | 2010-12-02 12:45:00 -0800 | [diff] [blame] | 464 | gInstructionFormatTable, |
| 465 | gInstructionIndexTypeTable, |
Dan Bornstein | 5432239 | 2010-11-17 14:16:56 -0800 | [diff] [blame] | 466 | gOpcodeFlagsTable, |
Dan Bornstein | e485276 | 2010-12-02 12:45:00 -0800 | [diff] [blame] | 467 | gInstructionWidthTable |
Dan Bornstein | 5432239 | 2010-11-17 14:16:56 -0800 | [diff] [blame] | 468 | }; |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 469 | |
| 470 | /* |
Dan Bornstein | 44a38f4 | 2010-11-10 17:34:32 -0800 | [diff] [blame] | 471 | * Handy macros for helping decode instructions. |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 472 | */ |
| 473 | #define FETCH(_offset) (insns[(_offset)]) |
Dan Bornstein | 44a38f4 | 2010-11-10 17:34:32 -0800 | [diff] [blame] | 474 | #define FETCH_u4(_offset) (fetch_u4_impl((_offset), insns)) |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 475 | #define INST_A(_inst) (((u2)(_inst) >> 8) & 0x0f) |
| 476 | #define INST_B(_inst) ((u2)(_inst) >> 12) |
| 477 | #define INST_AA(_inst) ((_inst) >> 8) |
| 478 | |
Dan Bornstein | 44a38f4 | 2010-11-10 17:34:32 -0800 | [diff] [blame] | 479 | /* Helper for FETCH_u4, above. */ |
| 480 | static inline u4 fetch_u4_impl(u4 offset, const u2* insns) { |
| 481 | return insns[offset] | ((u4) insns[offset+1] << 16); |
| 482 | } |
| 483 | |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 484 | /* |
| 485 | * Decode the instruction pointed to by "insns". |
| 486 | * |
| 487 | * Fills out the pieces of "pDec" that are affected by the current |
| 488 | * instruction. Does not touch anything else. |
| 489 | */ |
Dan Bornstein | 5432239 | 2010-11-17 14:16:56 -0800 | [diff] [blame] | 490 | void dexDecodeInstruction(const u2* insns, DecodedInstruction* pDec) |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 491 | { |
| 492 | u2 inst = *insns; |
Dan Bornstein | 9a1f816 | 2010-12-01 17:02:26 -0800 | [diff] [blame] | 493 | Opcode opcode = dexOpcodeFromCodeUnit(inst); |
Dan Bornstein | e485276 | 2010-12-02 12:45:00 -0800 | [diff] [blame] | 494 | InstructionFormat format = dexGetFormatFromOpcode(opcode); |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 495 | |
Dan Bornstein | 9a1f816 | 2010-12-01 17:02:26 -0800 | [diff] [blame] | 496 | pDec->opcode = opcode; |
Dan Bornstein | e485276 | 2010-12-02 12:45:00 -0800 | [diff] [blame] | 497 | pDec->indexType = dexGetIndexTypeFromOpcode(opcode); |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 498 | |
Dan Bornstein | ff70f76 | 2010-11-10 11:26:52 -0800 | [diff] [blame] | 499 | switch (format) { |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 500 | case kFmt10x: // op |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 501 | /* nothing to do; copy the AA bits out for the verifier */ |
| 502 | pDec->vA = INST_AA(inst); |
| 503 | break; |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 504 | case kFmt12x: // op vA, vB |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 505 | pDec->vA = INST_A(inst); |
| 506 | pDec->vB = INST_B(inst); |
| 507 | break; |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 508 | case kFmt11n: // op vA, #+B |
Carl Shapiro | de75089 | 2010-06-08 16:37:12 -0700 | [diff] [blame] | 509 | pDec->vA = INST_A(inst); |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 510 | pDec->vB = (s4) (INST_B(inst) << 28) >> 28; // sign extend 4-bit value |
| 511 | break; |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 512 | case kFmt11x: // op vAA |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 513 | pDec->vA = INST_AA(inst); |
| 514 | break; |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 515 | case kFmt10t: // op +AA |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 516 | pDec->vA = (s1) INST_AA(inst); // sign-extend 8-bit value |
| 517 | break; |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 518 | case kFmt20t: // op +AAAA |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 519 | pDec->vA = (s2) FETCH(1); // sign-extend 16-bit value |
| 520 | break; |
Andy McFadden | d325011 | 2010-11-03 14:32:42 -0700 | [diff] [blame] | 521 | case kFmt20bc: // [opt] op AA, thing@BBBB |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 522 | case kFmt21c: // op vAA, thing@BBBB |
| 523 | case kFmt22x: // op vAA, vBBBB |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 524 | pDec->vA = INST_AA(inst); |
| 525 | pDec->vB = FETCH(1); |
| 526 | break; |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 527 | case kFmt21s: // op vAA, #+BBBB |
| 528 | case kFmt21t: // op vAA, +BBBB |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 529 | pDec->vA = INST_AA(inst); |
| 530 | pDec->vB = (s2) FETCH(1); // sign-extend 16-bit value |
| 531 | break; |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 532 | case kFmt21h: // op vAA, #+BBBB0000[00000000] |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 533 | pDec->vA = INST_AA(inst); |
| 534 | /* |
| 535 | * The value should be treated as right-zero-extended, but we don't |
| 536 | * actually do that here. Among other things, we don't know if it's |
| 537 | * the top bits of a 32- or 64-bit value. |
| 538 | */ |
| 539 | pDec->vB = FETCH(1); |
| 540 | break; |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 541 | case kFmt23x: // op vAA, vBB, vCC |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 542 | pDec->vA = INST_AA(inst); |
| 543 | pDec->vB = FETCH(1) & 0xff; |
| 544 | pDec->vC = FETCH(1) >> 8; |
| 545 | break; |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 546 | case kFmt22b: // op vAA, vBB, #+CC |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 547 | pDec->vA = INST_AA(inst); |
| 548 | pDec->vB = FETCH(1) & 0xff; |
| 549 | pDec->vC = (s1) (FETCH(1) >> 8); // sign-extend 8-bit value |
| 550 | break; |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 551 | case kFmt22s: // op vA, vB, #+CCCC |
| 552 | case kFmt22t: // op vA, vB, +CCCC |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 553 | pDec->vA = INST_A(inst); |
| 554 | pDec->vB = INST_B(inst); |
| 555 | pDec->vC = (s2) FETCH(1); // sign-extend 16-bit value |
| 556 | break; |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 557 | case kFmt22c: // op vA, vB, thing@CCCC |
| 558 | case kFmt22cs: // [opt] op vA, vB, field offset CCCC |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 559 | pDec->vA = INST_A(inst); |
| 560 | pDec->vB = INST_B(inst); |
| 561 | pDec->vC = FETCH(1); |
| 562 | break; |
Dan Bornstein | ff70f76 | 2010-11-10 11:26:52 -0800 | [diff] [blame] | 563 | case kFmt30t: // op +AAAAAAAA |
Dan Bornstein | 44a38f4 | 2010-11-10 17:34:32 -0800 | [diff] [blame] | 564 | pDec->vA = FETCH_u4(1); // signed 32-bit value |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 565 | break; |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 566 | case kFmt31t: // op vAA, +BBBBBBBB |
Andy McFadden | d325011 | 2010-11-03 14:32:42 -0700 | [diff] [blame] | 567 | case kFmt31c: // op vAA, string@BBBBBBBB |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 568 | pDec->vA = INST_AA(inst); |
Dan Bornstein | 44a38f4 | 2010-11-10 17:34:32 -0800 | [diff] [blame] | 569 | pDec->vB = FETCH_u4(1); // 32-bit value |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 570 | break; |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 571 | case kFmt32x: // op vAAAA, vBBBB |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 572 | pDec->vA = FETCH(1); |
| 573 | pDec->vB = FETCH(2); |
| 574 | break; |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 575 | case kFmt31i: // op vAA, #+BBBBBBBB |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 576 | pDec->vA = INST_AA(inst); |
Dan Bornstein | 44a38f4 | 2010-11-10 17:34:32 -0800 | [diff] [blame] | 577 | pDec->vB = FETCH_u4(1); // signed 32-bit value |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 578 | break; |
Dan Bornstein | 7b3e9b0 | 2010-11-09 17:15:10 -0800 | [diff] [blame] | 579 | case kFmt35c: // op {vC, vD, vE, vF, vG}, thing@BBBB |
Andy McFadden | 3a1aedb | 2009-05-07 13:30:23 -0700 | [diff] [blame] | 580 | case kFmt35ms: // [opt] invoke-virtual+super |
Dan Bornstein | ff70f76 | 2010-11-10 11:26:52 -0800 | [diff] [blame] | 581 | case kFmt35mi: // [opt] inline invoke |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 582 | { |
| 583 | /* |
Dan Bornstein | 7b3e9b0 | 2010-11-09 17:15:10 -0800 | [diff] [blame] | 584 | * Note that the fields mentioned in the spec don't appear in |
| 585 | * their "usual" positions here compared to most formats. This |
| 586 | * was done so that the field names for the argument count and |
| 587 | * reference index match between this format and the corresponding |
| 588 | * range formats (3rc and friends). |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 589 | * |
Dan Bornstein | 7b3e9b0 | 2010-11-09 17:15:10 -0800 | [diff] [blame] | 590 | * Bottom line: The argument count is always in vA, and the |
Dan Bornstein | ff70f76 | 2010-11-10 11:26:52 -0800 | [diff] [blame] | 591 | * method constant (or equivalent) is always in vB. |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 592 | */ |
| 593 | u2 regList; |
| 594 | int i, count; |
| 595 | |
Dan Bornstein | 7b3e9b0 | 2010-11-09 17:15:10 -0800 | [diff] [blame] | 596 | pDec->vA = INST_B(inst); // This is labeled A in the spec. |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 597 | pDec->vB = FETCH(1); |
| 598 | regList = FETCH(2); |
| 599 | |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 600 | count = pDec->vA; |
Dan Bornstein | ff70f76 | 2010-11-10 11:26:52 -0800 | [diff] [blame] | 601 | |
| 602 | /* |
| 603 | * Copy the argument registers into the arg[] array, and |
| 604 | * also copy the first argument (if any) into vC. (The |
| 605 | * DecodedInstruction structure doesn't have separate |
| 606 | * fields for {vD, vE, vF, vG}, so there's no need to make |
| 607 | * copies of those.) Note that cases 5..2 fall through. |
| 608 | */ |
| 609 | switch (count) { |
| 610 | case 5: { |
| 611 | if (format == kFmt35mi) { |
| 612 | /* A fifth arg is verboten for inline invokes. */ |
Steve Block | e8e1ddc | 2012-01-05 23:21:27 +0000 | [diff] [blame] | 613 | ALOGW("Invalid arg count in 35mi (5)"); |
Dan Bornstein | ff70f76 | 2010-11-10 11:26:52 -0800 | [diff] [blame] | 614 | goto bail; |
| 615 | } |
Dan Bornstein | 7b3e9b0 | 2010-11-09 17:15:10 -0800 | [diff] [blame] | 616 | /* |
Dan Bornstein | ff70f76 | 2010-11-10 11:26:52 -0800 | [diff] [blame] | 617 | * Per note at the top of this format decoder, the |
| 618 | * fifth argument comes from the A field in the |
Dan Bornstein | 7b3e9b0 | 2010-11-09 17:15:10 -0800 | [diff] [blame] | 619 | * instruction, but it's labeled G in the spec. |
| 620 | */ |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 621 | pDec->arg[4] = INST_A(inst); |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 622 | } |
Dan Bornstein | ff70f76 | 2010-11-10 11:26:52 -0800 | [diff] [blame] | 623 | case 4: pDec->arg[3] = (regList >> 12) & 0x0f; |
| 624 | case 3: pDec->arg[2] = (regList >> 8) & 0x0f; |
| 625 | case 2: pDec->arg[1] = (regList >> 4) & 0x0f; |
| 626 | case 1: pDec->vC = pDec->arg[0] = regList & 0x0f; break; |
| 627 | case 0: break; // Valid, but no need to do anything. |
| 628 | default: |
Steve Block | e8e1ddc | 2012-01-05 23:21:27 +0000 | [diff] [blame] | 629 | ALOGW("Invalid arg count in 35c/35ms/35mi (%d)", count); |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 630 | goto bail; |
| 631 | } |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 632 | } |
| 633 | break; |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 634 | case kFmt3rc: // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB |
| 635 | case kFmt3rms: // [opt] invoke-virtual+super/range |
Dan Bornstein | 7b3e9b0 | 2010-11-09 17:15:10 -0800 | [diff] [blame] | 636 | case kFmt3rmi: // [opt] execute-inline/range |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 637 | pDec->vA = INST_AA(inst); |
| 638 | pDec->vB = FETCH(1); |
| 639 | pDec->vC = FETCH(2); |
| 640 | break; |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 641 | case kFmt51l: // op vAA, #+BBBBBBBBBBBBBBBB |
| 642 | pDec->vA = INST_AA(inst); |
Dan Bornstein | 44a38f4 | 2010-11-10 17:34:32 -0800 | [diff] [blame] | 643 | pDec->vB_wide = FETCH_u4(1) | ((u8) FETCH_u4(3) << 32); |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 644 | break; |
| 645 | default: |
Steve Block | e8e1ddc | 2012-01-05 23:21:27 +0000 | [diff] [blame] | 646 | ALOGW("Can't decode unexpected format %d (op=%d)", format, opcode); |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 647 | assert(false); |
| 648 | break; |
| 649 | } |
| 650 | |
| 651 | bail: |
| 652 | ; |
| 653 | } |
| 654 | |
| 655 | /* |
| 656 | * Return the width of the specified instruction, or 0 if not defined. Also |
| 657 | * works for special OP_NOP entries, including switch statement data tables |
| 658 | * and array data. |
| 659 | */ |
Dan Bornstein | e485276 | 2010-12-02 12:45:00 -0800 | [diff] [blame] | 660 | size_t dexGetWidthFromInstruction(const u2* insns) |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 661 | { |
Andy McFadden | 228a6b0 | 2010-05-04 15:02:32 -0700 | [diff] [blame] | 662 | size_t width; |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 663 | |
| 664 | if (*insns == kPackedSwitchSignature) { |
| 665 | width = 4 + insns[1] * 2; |
| 666 | } else if (*insns == kSparseSwitchSignature) { |
| 667 | width = 2 + insns[1] * 4; |
| 668 | } else if (*insns == kArrayDataSignature) { |
| 669 | u2 elemWidth = insns[1]; |
| 670 | u4 len = insns[2] | (((u4)insns[3]) << 16); |
Dan Bornstein | 1112216 | 2010-12-01 12:30:21 -0800 | [diff] [blame] | 671 | // The plus 1 is to round up for odd size and width. |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 672 | width = 4 + (elemWidth * len + 1) / 2; |
| 673 | } else { |
Dan Bornstein | e485276 | 2010-12-02 12:45:00 -0800 | [diff] [blame] | 674 | width = dexGetWidthFromOpcode(dexOpcodeFromCodeUnit(insns[0])); |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 675 | } |
Dan Bornstein | 4b6e9ba | 2010-12-02 10:35:48 -0800 | [diff] [blame] | 676 | |
The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 677 | return width; |
| 678 | } |