Nicolas Geoffray | 4fc7569 | 2020-01-13 21:49:22 +0000 | [diff] [blame] | 1 | %def unused(): |
| 2 | brk 42 |
| 3 | |
| 4 | %def op_const(): |
| 5 | /* const vAA, #+BBBBbbbb */ |
| 6 | lsr w3, wINST, #8 // w3<- AA |
| 7 | FETCH w0, 1 // w0<- bbbb (low) |
| 8 | FETCH w1, 2 // w1<- BBBB (high) |
| 9 | FETCH_ADVANCE_INST 3 // advance rPC, load wINST |
| 10 | orr w0, w0, w1, lsl #16 // w0<- BBBBbbbb |
| 11 | GET_INST_OPCODE ip // extract opcode from wINST |
| 12 | SET_VREG w0, w3 // vAA<- w0 |
| 13 | GOTO_OPCODE ip // jump to next instruction |
| 14 | |
| 15 | %def op_const_16(): |
| 16 | /* const/16 vAA, #+BBBB */ |
| 17 | FETCH_S w0, 1 // w0<- ssssBBBB (sign-extended) |
| 18 | lsr w3, wINST, #8 // w3<- AA |
| 19 | FETCH_ADVANCE_INST 2 // advance xPC, load wINST |
| 20 | SET_VREG w0, w3 // vAA<- w0 |
| 21 | GET_INST_OPCODE ip // extract opcode from wINST |
| 22 | GOTO_OPCODE ip // jump to next instruction |
| 23 | |
| 24 | %def op_const_4(): |
| 25 | /* const/4 vA, #+B */ |
| 26 | sbfx w1, wINST, #12, #4 // w1<- sssssssB |
| 27 | ubfx w0, wINST, #8, #4 // w0<- A |
| 28 | FETCH_ADVANCE_INST 1 // advance xPC, load wINST |
| 29 | GET_INST_OPCODE ip // ip<- opcode from xINST |
| 30 | SET_VREG w1, w0 // fp[A]<- w1 |
| 31 | GOTO_OPCODE ip // execute next instruction |
| 32 | |
| 33 | %def op_const_high16(): |
| 34 | /* const/high16 vAA, #+BBBB0000 */ |
| 35 | FETCH w0, 1 // r0<- 0000BBBB (zero-extended) |
| 36 | lsr w3, wINST, #8 // r3<- AA |
| 37 | lsl w0, w0, #16 // r0<- BBBB0000 |
| 38 | FETCH_ADVANCE_INST 2 // advance rPC, load rINST |
| 39 | SET_VREG w0, w3 // vAA<- r0 |
| 40 | GET_INST_OPCODE ip // extract opcode from rINST |
| 41 | GOTO_OPCODE ip // jump to next instruction |
| 42 | |
| 43 | %def op_const_object(jumbo="0", helper="nterp_load_object"): |
| 44 | // Fast-path which gets the object from thread-local cache. |
| 45 | FETCH_FROM_THREAD_CACHE x0, 2f |
Nicolas Geoffray | afae11f | 2021-11-10 16:45:13 +0000 | [diff] [blame] | 46 | TEST_IF_MARKING 3f |
Nicolas Geoffray | 4fc7569 | 2020-01-13 21:49:22 +0000 | [diff] [blame] | 47 | 1: |
| 48 | lsr w1, wINST, #8 // w1<- AA |
| 49 | .if $jumbo |
| 50 | FETCH_ADVANCE_INST 3 // advance rPC, load wINST |
| 51 | .else |
| 52 | FETCH_ADVANCE_INST 2 // advance rPC, load wINST |
| 53 | .endif |
| 54 | GET_INST_OPCODE ip // extract opcode from wINST |
| 55 | SET_VREG_OBJECT w0, w1 // vAA <- value |
| 56 | GOTO_OPCODE ip // jump to next instruction |
| 57 | 2: |
| 58 | EXPORT_PC |
| 59 | mov x0, xSELF |
| 60 | ldr x1, [sp] |
| 61 | mov x2, xPC |
| 62 | bl $helper |
| 63 | b 1b |
| 64 | 3: |
| 65 | bl art_quick_read_barrier_mark_reg00 |
| 66 | b 1b |
| 67 | |
| 68 | %def op_const_class(): |
| 69 | % op_const_object(jumbo="0", helper="nterp_get_class_or_allocate_object") |
| 70 | |
| 71 | %def op_const_method_handle(): |
| 72 | % op_const_object(jumbo="0") |
| 73 | |
| 74 | %def op_const_method_type(): |
| 75 | % op_const_object(jumbo="0") |
| 76 | |
| 77 | %def op_const_string(): |
| 78 | /* const/string vAA, String@BBBB */ |
| 79 | % op_const_object(jumbo="0") |
| 80 | |
| 81 | %def op_const_string_jumbo(): |
| 82 | /* const/string vAA, String@BBBBBBBB */ |
| 83 | % op_const_object(jumbo="1") |
| 84 | |
| 85 | %def op_const_wide(): |
| 86 | /* const-wide vAA, #+HHHHhhhhBBBBbbbb */ |
| 87 | FETCH w0, 1 // w0<- bbbb (low) |
| 88 | FETCH w1, 2 // w1<- BBBB (low middle) |
| 89 | FETCH w2, 3 // w2<- hhhh (high middle) |
| 90 | FETCH w3, 4 // w3<- HHHH (high) |
| 91 | lsr w4, wINST, #8 // r4<- AA |
| 92 | FETCH_ADVANCE_INST 5 // advance rPC, load wINST |
| 93 | GET_INST_OPCODE ip // extract opcode from wINST |
| 94 | orr w0, w0, w1, lsl #16 // w0<- BBBBbbbb |
| 95 | orr x0, x0, x2, lsl #32 // w0<- hhhhBBBBbbbb |
| 96 | orr x0, x0, x3, lsl #48 // w0<- HHHHhhhhBBBBbbbb |
| 97 | SET_VREG_WIDE x0, w4 |
| 98 | GOTO_OPCODE ip // jump to next instruction |
| 99 | |
| 100 | %def op_const_wide_16(): |
| 101 | /* const-wide/16 vAA, #+BBBB */ |
| 102 | FETCH_S x0, 1 // x0<- ssssssssssssBBBB (sign-extended) |
| 103 | lsr w3, wINST, #8 // w3<- AA |
| 104 | FETCH_ADVANCE_INST 2 // advance rPC, load rINST |
| 105 | GET_INST_OPCODE ip // extract opcode from rINST |
| 106 | SET_VREG_WIDE x0, w3 |
| 107 | GOTO_OPCODE ip // jump to next instruction |
| 108 | |
| 109 | %def op_const_wide_32(): |
| 110 | /* const-wide/32 vAA, #+BBBBbbbb */ |
| 111 | FETCH w0, 1 // x0<- 000000000000bbbb (low) |
| 112 | lsr w3, wINST, #8 // w3<- AA |
| 113 | FETCH_S x2, 2 // x2<- ssssssssssssBBBB (high) |
| 114 | FETCH_ADVANCE_INST 3 // advance rPC, load wINST |
| 115 | GET_INST_OPCODE ip // extract opcode from wINST |
| 116 | orr x0, x0, x2, lsl #16 // x0<- ssssssssBBBBbbbb |
| 117 | SET_VREG_WIDE x0, w3 |
| 118 | GOTO_OPCODE ip // jump to next instruction |
| 119 | |
| 120 | %def op_const_wide_high16(): |
| 121 | /* const-wide/high16 vAA, #+BBBB000000000000 */ |
| 122 | FETCH w0, 1 // w0<- 0000BBBB (zero-extended) |
| 123 | lsr w1, wINST, #8 // w1<- AA |
| 124 | FETCH_ADVANCE_INST 2 // advance rPC, load wINST |
| 125 | lsl x0, x0, #48 |
| 126 | SET_VREG_WIDE x0, w1 |
| 127 | GET_INST_OPCODE ip // extract opcode from wINST |
| 128 | GOTO_OPCODE ip // jump to next instruction |
| 129 | |
| 130 | %def op_monitor_enter(): |
| 131 | /* |
| 132 | * Synchronize on an object. |
| 133 | */ |
| 134 | /* monitor-enter vAA */ |
| 135 | EXPORT_PC |
| 136 | lsr w2, wINST, #8 // w2<- AA |
| 137 | GET_VREG w0, w2 |
| 138 | bl art_quick_lock_object |
| 139 | FETCH_ADVANCE_INST 1 |
| 140 | GET_INST_OPCODE ip // extract opcode from rINST |
| 141 | GOTO_OPCODE ip // jump to next instruction |
| 142 | |
| 143 | %def op_monitor_exit(): |
| 144 | /* |
| 145 | * Unlock an object. |
| 146 | * |
| 147 | * Exceptions that occur when unlocking a monitor need to appear as |
| 148 | * if they happened at the following instruction. See the Dalvik |
| 149 | * instruction spec. |
| 150 | */ |
| 151 | /* monitor-exit vAA */ |
| 152 | EXPORT_PC |
| 153 | lsr w2, wINST, #8 // w2<- AA |
| 154 | GET_VREG w0, w2 |
| 155 | bl art_quick_unlock_object |
| 156 | FETCH_ADVANCE_INST 1 |
| 157 | GET_INST_OPCODE ip // extract opcode from rINST |
| 158 | GOTO_OPCODE ip // jump to next instruction |
| 159 | |
| 160 | %def op_move(is_object="0"): |
| 161 | /* for move, move-object, long-to-int */ |
| 162 | /* op vA, vB */ |
| 163 | lsr w1, wINST, #12 // x1<- B from 15:12 |
| 164 | ubfx w0, wINST, #8, #4 // x0<- A from 11:8 |
| 165 | FETCH_ADVANCE_INST 1 // advance rPC, load wINST |
| 166 | GET_VREG w2, w1 // x2<- fp[B] |
| 167 | GET_INST_OPCODE ip // ip<- opcode from wINST |
| 168 | .if $is_object |
| 169 | SET_VREG_OBJECT w2, w0 // fp[A]<- x2 |
| 170 | .else |
| 171 | SET_VREG w2, w0 // fp[A]<- x2 |
| 172 | .endif |
| 173 | GOTO_OPCODE ip // execute next instruction |
| 174 | |
| 175 | %def op_move_16(is_object="0"): |
| 176 | /* for: move/16, move-object/16 */ |
| 177 | /* op vAAAA, vBBBB */ |
| 178 | FETCH w1, 2 // w1<- BBBB |
| 179 | FETCH w0, 1 // w0<- AAAA |
| 180 | FETCH_ADVANCE_INST 3 // advance xPC, load xINST |
| 181 | GET_VREG w2, w1 // w2<- fp[BBBB] |
| 182 | GET_INST_OPCODE ip // extract opcode from xINST |
| 183 | .if $is_object |
| 184 | SET_VREG_OBJECT w2, w0 // fp[AAAA]<- w2 |
| 185 | .else |
| 186 | SET_VREG w2, w0 // fp[AAAA]<- w2 |
| 187 | .endif |
| 188 | GOTO_OPCODE ip // jump to next instruction |
| 189 | |
| 190 | %def op_move_exception(): |
| 191 | /* move-exception vAA */ |
| 192 | lsr w2, wINST, #8 // w2<- AA |
| 193 | ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET] |
| 194 | FETCH_ADVANCE_INST 1 // advance rPC, load rINST |
| 195 | SET_VREG_OBJECT w3, w2 // fp[AA]<- exception obj |
| 196 | GET_INST_OPCODE ip // extract opcode from rINST |
| 197 | str xzr, [xSELF, #THREAD_EXCEPTION_OFFSET] // clear exception |
| 198 | GOTO_OPCODE ip // jump to next instruction |
| 199 | |
| 200 | %def op_move_from16(is_object="0"): |
| 201 | /* for: move/from16, move-object/from16 */ |
| 202 | /* op vAA, vBBBB */ |
| 203 | FETCH w1, 1 // r1<- BBBB |
| 204 | lsr w0, wINST, #8 // r0<- AA |
| 205 | FETCH_ADVANCE_INST 2 // advance rPC, load wINST |
| 206 | GET_VREG w2, w1 // r2<- fp[BBBB] |
| 207 | GET_INST_OPCODE ip // extract opcode from wINST |
| 208 | .if $is_object |
| 209 | SET_VREG_OBJECT w2, w0 // fp[AA]<- r2 |
| 210 | .else |
| 211 | SET_VREG w2, w0 // fp[AA]<- r2 |
| 212 | .endif |
| 213 | GOTO_OPCODE ip // jump to next instruction |
| 214 | |
| 215 | %def op_move_object(): |
| 216 | % op_move(is_object="1") |
| 217 | |
| 218 | %def op_move_object_16(): |
| 219 | % op_move_16(is_object="1") |
| 220 | |
| 221 | %def op_move_object_from16(): |
| 222 | % op_move_from16(is_object="1") |
| 223 | |
| 224 | %def op_move_result(is_object="0"): |
| 225 | /* for: move-result, move-result-object */ |
| 226 | /* op vAA */ |
| 227 | lsr w2, wINST, #8 // r2<- AA |
| 228 | FETCH_ADVANCE_INST 1 // advance rPC, load wINST |
| 229 | GET_INST_OPCODE ip // extract opcode from wINST |
| 230 | .if $is_object |
Nicolas Geoffray | aeb7f9f | 2020-11-11 13:39:18 +0000 | [diff] [blame] | 231 | SET_VREG_OBJECT w0, w2 // fp[AA]<- r0 |
Nicolas Geoffray | 4fc7569 | 2020-01-13 21:49:22 +0000 | [diff] [blame] | 232 | .else |
| 233 | SET_VREG w0, w2 // fp[AA]<- r0 |
| 234 | .endif |
| 235 | GOTO_OPCODE ip // jump to next instruction |
| 236 | |
| 237 | %def op_move_result_object(): |
| 238 | % op_move_result(is_object="1") |
| 239 | |
| 240 | %def op_move_result_wide(): |
| 241 | /* for: move-result-wide */ |
| 242 | /* op vAA */ |
| 243 | lsr w2, wINST, #8 // r2<- AA |
| 244 | FETCH_ADVANCE_INST 1 // advance rPC, load wINST |
| 245 | GET_INST_OPCODE ip // extract opcode from wINST |
| 246 | SET_VREG_WIDE x0, w2 // fp[AA]<- r0 |
| 247 | GOTO_OPCODE ip // jump to next instruction |
| 248 | |
| 249 | %def op_move_wide(): |
| 250 | /* move-wide vA, vB */ |
| 251 | /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ |
| 252 | lsr w3, wINST, #12 // w3<- B |
| 253 | ubfx w2, wINST, #8, #4 // w2<- A |
| 254 | GET_VREG_WIDE x3, w3 |
| 255 | FETCH_ADVANCE_INST 1 // advance rPC, load wINST |
| 256 | GET_INST_OPCODE ip // extract opcode from wINST |
| 257 | SET_VREG_WIDE x3, w2 |
| 258 | GOTO_OPCODE ip // jump to next instruction |
| 259 | |
| 260 | %def op_move_wide_16(): |
| 261 | /* move-wide/16 vAAAA, vBBBB */ |
| 262 | /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ |
| 263 | FETCH w3, 2 // w3<- BBBB |
| 264 | FETCH w2, 1 // w2<- AAAA |
| 265 | GET_VREG_WIDE x3, w3 |
| 266 | FETCH_ADVANCE_INST 3 // advance rPC, load rINST |
| 267 | SET_VREG_WIDE x3, w2 |
| 268 | GET_INST_OPCODE ip // extract opcode from rINST |
| 269 | GOTO_OPCODE ip // jump to next instruction |
| 270 | |
| 271 | %def op_move_wide_from16(): |
| 272 | /* move-wide/from16 vAA, vBBBB */ |
| 273 | /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ |
| 274 | FETCH w3, 1 // w3<- BBBB |
| 275 | lsr w2, wINST, #8 // w2<- AA |
| 276 | GET_VREG_WIDE x3, w3 |
| 277 | FETCH_ADVANCE_INST 2 // advance rPC, load wINST |
| 278 | GET_INST_OPCODE ip // extract opcode from wINST |
| 279 | SET_VREG_WIDE x3, w2 |
| 280 | GOTO_OPCODE ip // jump to next instruction |
| 281 | |
| 282 | %def op_nop(): |
| 283 | FETCH_ADVANCE_INST 1 // advance to next instr, load rINST |
| 284 | GET_INST_OPCODE ip // ip<- opcode from rINST |
| 285 | GOTO_OPCODE ip // execute it |
| 286 | |
| 287 | %def op_unused_3e(): |
| 288 | % unused() |
| 289 | |
| 290 | %def op_unused_3f(): |
| 291 | % unused() |
| 292 | |
| 293 | %def op_unused_40(): |
| 294 | % unused() |
| 295 | |
| 296 | %def op_unused_41(): |
| 297 | % unused() |
| 298 | |
| 299 | %def op_unused_42(): |
| 300 | % unused() |
| 301 | |
| 302 | %def op_unused_43(): |
| 303 | % unused() |
| 304 | |
David Srbecky | 61c6242 | 2021-04-27 16:22:48 +0100 | [diff] [blame] | 305 | %def op_unused_73(): |
| 306 | % unused() |
| 307 | |
Nicolas Geoffray | 4fc7569 | 2020-01-13 21:49:22 +0000 | [diff] [blame] | 308 | %def op_unused_79(): |
| 309 | % unused() |
| 310 | |
| 311 | %def op_unused_7a(): |
| 312 | % unused() |
| 313 | |
David Srbecky | c5cd589 | 2021-03-23 08:09:15 +0000 | [diff] [blame] | 314 | %def op_unused_e3(): |
| 315 | % unused() |
| 316 | |
| 317 | %def op_unused_e4(): |
| 318 | % unused() |
| 319 | |
| 320 | %def op_unused_e5(): |
| 321 | % unused() |
| 322 | |
| 323 | %def op_unused_e6(): |
| 324 | % unused() |
| 325 | |
| 326 | %def op_unused_e7(): |
| 327 | % unused() |
| 328 | |
| 329 | %def op_unused_e8(): |
| 330 | % unused() |
| 331 | |
| 332 | %def op_unused_e9(): |
| 333 | % unused() |
| 334 | |
| 335 | %def op_unused_ea(): |
| 336 | % unused() |
| 337 | |
| 338 | %def op_unused_eb(): |
| 339 | % unused() |
| 340 | |
| 341 | %def op_unused_ec(): |
| 342 | % unused() |
| 343 | |
| 344 | %def op_unused_ed(): |
| 345 | % unused() |
| 346 | |
| 347 | %def op_unused_ee(): |
| 348 | % unused() |
| 349 | |
| 350 | %def op_unused_ef(): |
| 351 | % unused() |
| 352 | |
| 353 | %def op_unused_f0(): |
| 354 | % unused() |
| 355 | |
| 356 | %def op_unused_f1(): |
| 357 | % unused() |
| 358 | |
| 359 | %def op_unused_f2(): |
| 360 | % unused() |
| 361 | |
Nicolas Geoffray | 4fc7569 | 2020-01-13 21:49:22 +0000 | [diff] [blame] | 362 | %def op_unused_f3(): |
| 363 | % unused() |
| 364 | |
| 365 | %def op_unused_f4(): |
| 366 | % unused() |
| 367 | |
| 368 | %def op_unused_f5(): |
| 369 | % unused() |
| 370 | |
| 371 | %def op_unused_f6(): |
| 372 | % unused() |
| 373 | |
| 374 | %def op_unused_f7(): |
| 375 | % unused() |
| 376 | |
| 377 | %def op_unused_f8(): |
| 378 | % unused() |
| 379 | |
| 380 | %def op_unused_f9(): |
| 381 | % unused() |
| 382 | |
| 383 | %def op_unused_fc(): |
| 384 | % unused() |
| 385 | |
| 386 | %def op_unused_fd(): |
| 387 | % unused() |