1/* 2 * This file was generated automatically by gen-mterp.py for 'x86'. 3 * 4 * --> DO NOT EDIT <-- 5 */ 6 7/* File: x86/header.S */ 8/* 9 * Copyright (C) 2008 The Android Open Source Project 10 * 11 * Licensed under the Apache License, Version 2.0 (the "License"); 12 * you may not use this file except in compliance with the License. 13 * You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, software 18 * distributed under the License is distributed on an "AS IS" BASIS, 19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 * See the License for the specific language governing permissions and 21 * limitations under the License. 22 */ 23/* 24 * 32-bit x86 definitions and declarations. 25 */ 26 27/* 28386 ABI general notes: 29 30Caller save set: 31 eax, edx, ecx, st(0)-st(7) 32Callee save set: 33 ebx, esi, edi, ebp 34Return regs: 35 32-bit in eax 36 64-bit in edx:eax (low-order 32 in eax) 37 fp on top of fp stack st(0) 38 39Parameters passed on stack, pushed right-to-left. On entry to target, first 40parm is at 4(%esp). Traditional entry code is: 41 42functEntry: 43 push %ebp # save old frame pointer 44 mov %ebp,%esp # establish new frame pointer 45 sub FrameSize,%esp # Allocate storage for spill, locals & outs 46 47Once past the prologue, arguments are referenced at ((argno + 2)*4)(%ebp) 48 49Stack must be 16-byte aligned to support SSE in native code. 50 51If we're not doing variable stack allocation (alloca), the frame pointer can be 52eliminated and all arg references adjusted to be esp relative. 53 54Mterp notes: 55 56Some key interpreter variables will be assigned to registers. Note that each 57will also have an associated spill location (mostly useful for those assigned 58to callee save registers). 59 60 nick reg purpose 61 rPC esi interpreted program counter, used for fetching instructions 62 rFP edi interpreted frame pointer, used for accessing locals and args 63 rINSTw bx first 16-bit code of current instruction 64 rINSTbl bl opcode portion of instruction word 65 rINSTbh bh high byte of inst word, usually contains src/tgt reg names 66 rIBASE edx base of instruction handler table 67 68Notes: 69 o High order 16 bits of ebx must be zero on entry to handler 70 o rPC, rFP, rINSTw/rINSTbl valid on handler entry and exit 71 o eax and ecx are scratch, rINSTw/ebx sometimes scratch 72 73*/ 74 75#define rSELF 8(%ebp) 76#define rPC %esi 77#define rFP %edi 78#define rINST %ebx 79#define rINSTw %bx 80#define rINSTbh %bh 81#define rINSTbl %bl 82#define rIBASE %edx 83 84 85/* Frame diagram while executing dvmMterpStdRun, high to low addresses */ 86#define IN_ARG0 ( 8) 87#define CALLER_RP ( 4) 88#define PREV_FP ( 0) 89/* Spill offsets relative to %ebp */ 90#define EDI_SPILL ( -4) 91#define ESI_SPILL ( -8) 92#define EBX_SPILL (-12) 93#define rPC_SPILL (-16) 94#define rFP_SPILL (-20) 95#define rINST_SPILL (-24) 96#define rIBASE_SPILL (-28) 97#define TMP_SPILL1 (-32) 98#define TMP_SPILL2 (-36) 99#define TMP_SPILL3 (-20) 100#define LOCAL0_OFFSET (-44) 101#define LOCAL1_OFFSET (-48) 102#define LOCAL2_OFFSET (-52) 103/* Out Arg offsets, relative to %esp */ 104#define OUT_ARG4 ( 16) 105#define OUT_ARG3 ( 12) 106#define OUT_ARG2 ( 8) 107#define OUT_ARG1 ( 4) 108#define OUT_ARG0 ( 0) /* <- dvmMterpStdRun esp */ 109#if defined(WITH_JIT) 110/* for spill region: increase size by 48 (to keep 16-byte alignment) */ 111/* 76 + 48 = 124 */ 112#define JIT_SPILL (-56) 113#define FRAME_SIZE 124 114#else 115#define FRAME_SIZE 76 116#endif 117 118#define SPILL(reg) movl reg##,reg##_SPILL(%ebp) 119#define UNSPILL(reg) movl reg##_SPILL(%ebp),reg 120#define SPILL_TMP1(reg) movl reg,TMP_SPILL1(%ebp) 121#define UNSPILL_TMP1(reg) movl TMP_SPILL1(%ebp),reg 122#define SPILL_TMP2(reg) movl reg,TMP_SPILL2(%ebp) 123#define UNSPILL_TMP2(reg) movl TMP_SPILL2(%ebp),reg 124#define SPILL_TMP3(reg) movl reg,TMP_SPILL3(%ebp) 125#define UNSPILL_TMP3(reg) movl TMP_SPILL3(%ebp),reg 126 127#if defined(WITH_JIT) 128.macro GET_JIT_PROF_TABLE _self _reg 129 movl offThread_pJitProfTable(\_self),\_reg 130.endm 131.macro GET_JIT_THRESHOLD _self _reg 132 movl offThread_jitThreshold(\_self),\_reg 133.endm 134#endif 135 136/* save/restore the PC and/or FP from the self struct */ 137.macro SAVE_PC_FP_TO_SELF _reg 138 movl rSELF,\_reg 139 movl rPC,offThread_pc(\_reg) 140 movl rFP,offThread_curFrame(\_reg) 141.endm 142 143.macro LOAD_PC_FP_FROM_SELF 144 movl rSELF,rFP 145 movl offThread_pc(rFP),rPC 146 movl offThread_curFrame(rFP),rFP 147.endm 148 149/* The interpreter assumes a properly aligned stack on entry, and 150 * will preserve 16-byte alignment. 151 */ 152 153/* 154 * "export" the PC to the interpreted stack frame, f/b/o future exception 155 * objects. Must be done *before* something throws. 156 * 157 * In C this is "SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc", i.e. 158 * fp - sizeof(StackSaveArea) + offsetof(SaveArea, xtra.currentPc) 159 * 160 * It's okay to do this more than once. 161 */ 162.macro EXPORT_PC 163 movl rPC, (-sizeofStackSaveArea + offStackSaveArea_currentPc)(rFP) 164.endm 165 166.macro GET_PC 167 movl (-sizeofStackSaveArea + offStackSaveArea_currentPc)(rFP), rPC 168.endm 169 170/* 171 * Given a frame pointer, find the stack save area. 172 * 173 * In C this is "((StackSaveArea*)(_fp) -1)". 174 */ 175.macro SAVEAREA_FROM_FP _reg 176 leal -sizeofStackSaveArea(rFP), \_reg 177.endm 178 179/* 180 * Fetch the next instruction from rPC into rINSTw. Does not advance rPC. 181 */ 182.macro FETCH_INST 183 movzwl (rPC),rINST 184.endm 185 186/* 187 * Fetch the opcode byte and zero-extend it into _reg. Must be used 188 * in conjunction with GOTO_NEXT_R 189 */ 190.macro FETCH_INST_R _reg 191 movzbl (rPC),\_reg 192.endm 193 194/* 195 * Fetch the opcode byte at _count words offset from rPC and zero-extend 196 * it into _reg. Must be used in conjunction with GOTO_NEXT_R 197 */ 198.macro FETCH_INST_OPCODE _count _reg 199 movzbl \_count*2(rPC),\_reg 200.endm 201 202/* 203 * Fetch the nth instruction word from rPC into rINSTw. Does not advance 204 * rPC, and _count is in words 205 */ 206.macro FETCH_INST_WORD _count 207 movzwl \_count*2(rPC),rINST 208.endm 209 210/* 211 * Fetch instruction word indexed (used for branching). 212 * Index is in instruction word units. 213 */ 214.macro FETCH_INST_INDEXED _reg 215 movzwl (rPC,\_reg,2),rINST 216.endm 217 218/* 219 * Advance rPC by instruction count 220 */ 221.macro ADVANCE_PC _count 222 leal 2*\_count(rPC),rPC 223.endm 224 225/* 226 * Advance rPC by branch offset in register 227 */ 228.macro ADVANCE_PC_INDEXED _reg 229 leal (rPC,\_reg,2),rPC 230.endm 231 232.macro GOTO_NEXT 233 movzx rINSTbl,%eax 234 movzbl rINSTbh,rINST 235 jmp *(rIBASE,%eax,4) 236.endm 237 238 /* 239 * Version of GOTO_NEXT that assumes _reg preloaded with opcode. 240 * Should be paired with FETCH_INST_R 241 */ 242.macro GOTO_NEXT_R _reg 243 movzbl 1(rPC),rINST 244 jmp *(rIBASE,\_reg,4) 245.endm 246 247/* 248 * Get/set the 32-bit value from a Dalvik register. 249 */ 250.macro GET_VREG_R _reg _vreg 251 movl (rFP,\_vreg,4),\_reg 252.endm 253 254.macro SET_VREG _reg _vreg 255 movl \_reg,(rFP,\_vreg,4) 256.endm 257 258.macro GET_VREG_WORD _reg _vreg _offset 259 movl 4*(\_offset)(rFP,\_vreg,4),\_reg 260.endm 261 262.macro SET_VREG_WORD _reg _vreg _offset 263 movl \_reg,4*(\_offset)(rFP,\_vreg,4) 264.endm 265 266#define sReg0 LOCAL0_OFFSET(%ebp) 267#define sReg1 LOCAL1_OFFSET(%ebp) 268#define sReg2 LOCAL2_OFFSET(%ebp) 269 270 /* 271 * x86 JIT Helpers 272 */ 273 274 .macro dumpSwitch _regData _regScratch1 _regScratch2 275 .endm 276 277 /* 278 * Hard coded helper values. 279 */ 280 281.balign 16 282 283.LdoubNeg: 284 .quad 0x8000000000000000 285 286.L64bits: 287 .quad 0xFFFFFFFFFFFFFFFF 288 289.LshiftMask2: 290 .quad 0x0000000000000000 291.LshiftMask: 292 .quad 0x000000000000003F 293 294.Lvalue64: 295 .quad 0x0000000000000040 296 297.LvaluePosInfLong: 298 .quad 0x7FFFFFFFFFFFFFFF 299 300.LvalueNegInfLong: 301 .quad 0x8000000000000000 302 303.LvalueNanLong: 304 .quad 0x0000000000000000 305 306.LintMin: 307.long 0x80000000 308 309.LintMax: 310.long 0x7FFFFFFF 311 312 313/* 314 * This is a #include, not a %include, because we want the C pre-processor 315 * to expand the macros into assembler assignment statements. 316 */ 317#include "../common/asm-constants.h" 318 319#if defined(WITH_JIT) 320#include "../common/jit-config.h" 321#endif 322 323 324 .global dvmAsmInstructionStartCode 325 .type dvmAsmInstructionStartCode, %function 326dvmAsmInstructionStartCode = .L_OP_NOP 327 .text 328 329/* ------------------------------ */ 330.L_OP_NOP: /* 0x00 */ 331/* File: x86/OP_NOP.S */ 332 FETCH_INST_OPCODE 1 %ecx 333 ADVANCE_PC 1 334 GOTO_NEXT_R %ecx 335 336/* ------------------------------ */ 337.L_OP_MOVE: /* 0x01 */ 338/* File: x86/OP_MOVE.S */ 339 /* for move, move-object, long-to-int */ 340 /* op vA, vB */ 341 movzbl rINSTbl,%eax # eax<- BA 342 andb $0xf,%al # eax<- A 343 shrl $4,rINST # rINST<- B 344 GET_VREG_R rINST rINST 345 FETCH_INST_OPCODE 1 %ecx 346 ADVANCE_PC 1 347 SET_VREG rINST %eax # fp[A]<-fp[B] 348 GOTO_NEXT_R %ecx 349 350/* ------------------------------ */ 351.L_OP_MOVE_FROM16: /* 0x02 */ 352/* File: x86/OP_MOVE_FROM16.S */ 353 /* for: move/from16, move-object/from16 */ 354 /* op vAA, vBBBB */ 355 movzx rINSTbl,%eax # eax <= AA 356 movw 2(rPC),rINSTw # rINSTw <= BBBB 357 GET_VREG_R rINST rINST # rINST- fp[BBBB] 358 FETCH_INST_OPCODE 2 %ecx 359 ADVANCE_PC 2 360 SET_VREG rINST %eax # fp[AA]<- ecx] 361 GOTO_NEXT_R %ecx 362 363/* ------------------------------ */ 364.L_OP_MOVE_16: /* 0x03 */ 365/* File: x86/OP_MOVE_16.S */ 366 /* for: move/16, move-object/16 */ 367 /* op vAAAA, vBBBB */ 368 movzwl 4(rPC),%ecx # ecx<- BBBB 369 movzwl 2(rPC),%eax # eax<- AAAA 370 GET_VREG_R rINST %ecx 371 FETCH_INST_OPCODE 3 %ecx 372 ADVANCE_PC 3 373 SET_VREG rINST %eax 374 GOTO_NEXT_R %ecx 375 376/* ------------------------------ */ 377.L_OP_MOVE_WIDE: /* 0x04 */ 378/* File: x86/OP_MOVE_WIDE.S */ 379 /* move-wide vA, vB */ 380 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 381 movzbl rINSTbl,%ecx # ecx <- BA 382 sarl $4,rINST # rINST<- B 383 GET_VREG_WORD %eax rINST 0 # eax<- v[B+0] 384 GET_VREG_WORD rINST rINST 1 # rINST<- v[B+1] 385 andb $0xf,%cl # ecx <- A 386 SET_VREG_WORD rINST %ecx 1 # v[A+1]<- rINST 387 SET_VREG_WORD %eax %ecx 0 # v[A+0]<- eax 388 FETCH_INST_OPCODE 1 %ecx 389 ADVANCE_PC 1 390 GOTO_NEXT_R %ecx 391 392/* ------------------------------ */ 393.L_OP_MOVE_WIDE_FROM16: /* 0x05 */ 394/* File: x86/OP_MOVE_WIDE_FROM16.S */ 395 /* move-wide/from16 vAA, vBBBB */ 396 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 397 movzwl 2(rPC),%ecx # ecx<- BBBB 398 movzbl rINSTbl,%eax # eax<- AAAA 399 GET_VREG_WORD rINST %ecx 0 # rINST<- v[BBBB+0] 400 GET_VREG_WORD %ecx %ecx 1 # ecx<- v[BBBB+1] 401 SET_VREG_WORD rINST %eax 0 # v[AAAA+0]<- rINST 402 SET_VREG_WORD %ecx %eax 1 # v[AAAA+1]<- eax 403 FETCH_INST_OPCODE 2 %ecx 404 ADVANCE_PC 2 405 GOTO_NEXT_R %ecx 406 407/* ------------------------------ */ 408.L_OP_MOVE_WIDE_16: /* 0x06 */ 409/* File: x86/OP_MOVE_WIDE_16.S */ 410 /* move-wide/16 vAAAA, vBBBB */ 411 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 412 movzwl 4(rPC),%ecx # ecx<- BBBB 413 movzwl 2(rPC),%eax # eax<- AAAA 414 GET_VREG_WORD rINST %ecx 0 # rINSTw_WORD<- v[BBBB+0] 415 GET_VREG_WORD %ecx %ecx 1 # ecx<- v[BBBB+1] 416 SET_VREG_WORD rINST %eax 0 # v[AAAA+0]<- rINST 417 SET_VREG_WORD %ecx %eax 1 # v[AAAA+1]<- ecx 418 FETCH_INST_OPCODE 3 %ecx 419 ADVANCE_PC 3 420 GOTO_NEXT_R %ecx 421 422/* ------------------------------ */ 423.L_OP_MOVE_OBJECT: /* 0x07 */ 424/* File: x86/OP_MOVE_OBJECT.S */ 425/* File: x86/OP_MOVE.S */ 426 /* for move, move-object, long-to-int */ 427 /* op vA, vB */ 428 movzbl rINSTbl,%eax # eax<- BA 429 andb $0xf,%al # eax<- A 430 shrl $4,rINST # rINST<- B 431 GET_VREG_R rINST rINST 432 FETCH_INST_OPCODE 1 %ecx 433 ADVANCE_PC 1 434 SET_VREG rINST %eax # fp[A]<-fp[B] 435 GOTO_NEXT_R %ecx 436 437 438/* ------------------------------ */ 439.L_OP_MOVE_OBJECT_FROM16: /* 0x08 */ 440/* File: x86/OP_MOVE_OBJECT_FROM16.S */ 441/* File: x86/OP_MOVE_FROM16.S */ 442 /* for: move/from16, move-object/from16 */ 443 /* op vAA, vBBBB */ 444 movzx rINSTbl,%eax # eax <= AA 445 movw 2(rPC),rINSTw # rINSTw <= BBBB 446 GET_VREG_R rINST rINST # rINST- fp[BBBB] 447 FETCH_INST_OPCODE 2 %ecx 448 ADVANCE_PC 2 449 SET_VREG rINST %eax # fp[AA]<- ecx] 450 GOTO_NEXT_R %ecx 451 452 453/* ------------------------------ */ 454.L_OP_MOVE_OBJECT_16: /* 0x09 */ 455/* File: x86/OP_MOVE_OBJECT_16.S */ 456/* File: x86/OP_MOVE_16.S */ 457 /* for: move/16, move-object/16 */ 458 /* op vAAAA, vBBBB */ 459 movzwl 4(rPC),%ecx # ecx<- BBBB 460 movzwl 2(rPC),%eax # eax<- AAAA 461 GET_VREG_R rINST %ecx 462 FETCH_INST_OPCODE 3 %ecx 463 ADVANCE_PC 3 464 SET_VREG rINST %eax 465 GOTO_NEXT_R %ecx 466 467 468/* ------------------------------ */ 469.L_OP_MOVE_RESULT: /* 0x0a */ 470/* File: x86/OP_MOVE_RESULT.S */ 471 /* for: move-result, move-result-object */ 472 /* op vAA */ 473 movl rSELF,%eax # eax<- rSELF 474 movl offThread_retval(%eax),%eax # eax<- self->retval.l 475 FETCH_INST_OPCODE 1 %ecx 476 ADVANCE_PC 1 477 SET_VREG %eax rINST # fp[AA]<- retval.l 478 GOTO_NEXT_R %ecx 479 480/* ------------------------------ */ 481.L_OP_MOVE_RESULT_WIDE: /* 0x0b */ 482/* File: x86/OP_MOVE_RESULT_WIDE.S */ 483 /* move-result-wide vAA */ 484 movl rSELF,%ecx 485 movl offThread_retval(%ecx),%eax 486 movl 4+offThread_retval(%ecx),%ecx 487 SET_VREG_WORD %eax rINST 0 # v[AA+0] <- eax 488 SET_VREG_WORD %ecx rINST 1 # v[AA+1] <- ecx 489 FETCH_INST_OPCODE 1 %ecx 490 ADVANCE_PC 1 491 GOTO_NEXT_R %ecx 492 493/* ------------------------------ */ 494.L_OP_MOVE_RESULT_OBJECT: /* 0x0c */ 495/* File: x86/OP_MOVE_RESULT_OBJECT.S */ 496/* File: x86/OP_MOVE_RESULT.S */ 497 /* for: move-result, move-result-object */ 498 /* op vAA */ 499 movl rSELF,%eax # eax<- rSELF 500 movl offThread_retval(%eax),%eax # eax<- self->retval.l 501 FETCH_INST_OPCODE 1 %ecx 502 ADVANCE_PC 1 503 SET_VREG %eax rINST # fp[AA]<- retval.l 504 GOTO_NEXT_R %ecx 505 506 507/* ------------------------------ */ 508.L_OP_MOVE_EXCEPTION: /* 0x0d */ 509/* File: x86/OP_MOVE_EXCEPTION.S */ 510 /* move-exception vAA */ 511 movl rSELF,%ecx 512 movl offThread_exception(%ecx),%eax # eax<- dvmGetException bypass 513 SET_VREG %eax rINST # fp[AA]<- exception object 514 FETCH_INST_OPCODE 1 %eax 515 ADVANCE_PC 1 516 movl $0,offThread_exception(%ecx) # dvmClearException bypass 517 GOTO_NEXT_R %eax 518 519/* ------------------------------ */ 520.L_OP_RETURN_VOID: /* 0x0e */ 521/* File: x86/OP_RETURN_VOID.S */ 522 jmp common_returnFromMethod 523 524/* ------------------------------ */ 525.L_OP_RETURN: /* 0x0f */ 526/* File: x86/OP_RETURN.S */ 527 /* 528 * Return a 32-bit value. Copies the return value into the "self" 529 * structure, then jumps to the return handler. 530 * 531 * for: return, return-object 532 */ 533 /* op vAA */ 534 movl rSELF,%ecx 535 GET_VREG_R %eax rINST # eax<- vAA 536 movl %eax,offThread_retval(%ecx) # retval.i <- AA 537 jmp common_returnFromMethod 538 539/* ------------------------------ */ 540.L_OP_RETURN_WIDE: /* 0x10 */ 541/* File: x86/OP_RETURN_WIDE.S */ 542 /* 543 * Return a 64-bit value. Copies the return value into the "self" 544 * structure, then jumps to the return handler. 545 */ 546 /* return-wide vAA */ 547 movl rSELF,%ecx 548 GET_VREG_WORD %eax rINST 0 # eax<- v[AA+0] 549 GET_VREG_WORD rINST rINST 1 # rINST<- v[AA+1] 550 movl %eax,offThread_retval(%ecx) 551 movl rINST,4+offThread_retval(%ecx) 552 jmp common_returnFromMethod 553 554/* ------------------------------ */ 555.L_OP_RETURN_OBJECT: /* 0x11 */ 556/* File: x86/OP_RETURN_OBJECT.S */ 557/* File: x86/OP_RETURN.S */ 558 /* 559 * Return a 32-bit value. Copies the return value into the "self" 560 * structure, then jumps to the return handler. 561 * 562 * for: return, return-object 563 */ 564 /* op vAA */ 565 movl rSELF,%ecx 566 GET_VREG_R %eax rINST # eax<- vAA 567 movl %eax,offThread_retval(%ecx) # retval.i <- AA 568 jmp common_returnFromMethod 569 570 571/* ------------------------------ */ 572.L_OP_CONST_4: /* 0x12 */ 573/* File: x86/OP_CONST_4.S */ 574 /* const/4 vA, #+B */ 575 movsx rINSTbl,%eax # eax<-ssssssBx 576 movl $0xf,rINST 577 andl %eax,rINST # rINST<- A 578 FETCH_INST_OPCODE 1 %ecx 579 ADVANCE_PC 1 580 sarl $4,%eax 581 SET_VREG %eax rINST 582 GOTO_NEXT_R %ecx 583 584/* ------------------------------ */ 585.L_OP_CONST_16: /* 0x13 */ 586/* File: x86/OP_CONST_16.S */ 587 /* const/16 vAA, #+BBBB */ 588 movswl 2(rPC),%ecx # ecx<- ssssBBBB 589 FETCH_INST_OPCODE 2 %eax 590 ADVANCE_PC 2 591 SET_VREG %ecx rINST # vAA<- ssssBBBB 592 GOTO_NEXT_R %eax 593 594/* ------------------------------ */ 595.L_OP_CONST: /* 0x14 */ 596/* File: x86/OP_CONST.S */ 597 /* const vAA, #+BBBBbbbb */ 598 movl 2(rPC),%eax # grab all 32 bits at once 599 movl rINST,rINST # rINST<- AA 600 FETCH_INST_OPCODE 3 %ecx 601 ADVANCE_PC 3 602 SET_VREG %eax rINST # vAA<- eax 603 GOTO_NEXT_R %ecx 604 605/* ------------------------------ */ 606.L_OP_CONST_HIGH16: /* 0x15 */ 607/* File: x86/OP_CONST_HIGH16.S */ 608 /* const/high16 vAA, #+BBBB0000 */ 609 movzwl 2(rPC),%eax # eax<- 0000BBBB 610 FETCH_INST_OPCODE 2 %ecx 611 ADVANCE_PC 2 612 sall $16,%eax # eax<- BBBB0000 613 SET_VREG %eax rINST # vAA<- eax 614 GOTO_NEXT_R %ecx 615 616/* ------------------------------ */ 617.L_OP_CONST_WIDE_16: /* 0x16 */ 618/* File: x86/OP_CONST_WIDE_16.S */ 619 /* const-wide/16 vAA, #+BBBB */ 620 movswl 2(rPC),%eax # eax<- ssssBBBB 621 SPILL(rIBASE) # preserve rIBASE (cltd trashes it) 622 cltd # rIBASE:eax<- ssssssssssssBBBB 623 SET_VREG_WORD rIBASE rINST 1 # store msw 624 FETCH_INST_OPCODE 2 %ecx 625 UNSPILL(rIBASE) # restore rIBASE 626 SET_VREG_WORD %eax rINST 0 # store lsw 627 ADVANCE_PC 2 628 GOTO_NEXT_R %ecx 629 630/* ------------------------------ */ 631.L_OP_CONST_WIDE_32: /* 0x17 */ 632/* File: x86/OP_CONST_WIDE_32.S */ 633 /* const-wide/32 vAA, #+BBBBbbbb */ 634 movl 2(rPC),%eax # eax<- BBBBbbbb 635 SPILL(rIBASE) # save rIBASE (cltd trashes it) 636 cltd # rIBASE:eax<- ssssssssssssBBBB 637 SET_VREG_WORD rIBASE rINST,1 # store msw 638 FETCH_INST_OPCODE 3 %ecx 639 UNSPILL(rIBASE) # restore rIBASE 640 SET_VREG_WORD %eax rINST 0 # store lsw 641 ADVANCE_PC 3 642 GOTO_NEXT_R %ecx 643 644/* ------------------------------ */ 645.L_OP_CONST_WIDE: /* 0x18 */ 646/* File: x86/OP_CONST_WIDE.S */ 647 /* const-wide vAA, #+HHHHhhhhBBBBbbbb */ 648 movl 2(rPC),%eax # eax<- lsw 649 movzbl rINSTbl,%ecx # ecx<- AA 650 movl 6(rPC),rINST # rINST<- msw 651 leal (rFP,%ecx,4),%ecx # dst addr 652 movl rINST,4(%ecx) 653 movl %eax,(%ecx) 654 FETCH_INST_OPCODE 5 %ecx 655 ADVANCE_PC 5 656 GOTO_NEXT_R %ecx 657 658/* ------------------------------ */ 659.L_OP_CONST_WIDE_HIGH16: /* 0x19 */ 660/* File: x86/OP_CONST_WIDE_HIGH16.S */ 661 /* const-wide/high16 vAA, #+BBBB000000000000 */ 662 movzwl 2(rPC),%eax # eax<- 0000BBBB 663 FETCH_INST_OPCODE 2 %ecx 664 ADVANCE_PC 2 665 sall $16,%eax # eax<- BBBB0000 666 SET_VREG_WORD %eax rINST 1 # v[AA+1]<- eax 667 xorl %eax,%eax 668 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- eax 669 GOTO_NEXT_R %ecx 670 671/* ------------------------------ */ 672.L_OP_CONST_STRING: /* 0x1a */ 673/* File: x86/OP_CONST_STRING.S */ 674 675 /* const/string vAA, String@BBBB */ 676 movl rSELF,%ecx 677 movzwl 2(rPC),%eax # eax<- BBBB 678 movl offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex 679 movl offDvmDex_pResStrings(%ecx),%ecx # ecx<- dvmDex->pResStrings 680 movl (%ecx,%eax,4),%eax # eax<- rResString[BBBB] 681 FETCH_INST_OPCODE 2 %ecx 682 testl %eax,%eax # resolved yet? 683 je .LOP_CONST_STRING_resolve 684 SET_VREG %eax rINST # vAA<- rResString[BBBB] 685 ADVANCE_PC 2 686 GOTO_NEXT_R %ecx 687 688/* This is the less common path, so we'll redo some work 689 here rather than force spills on the common path */ 690.LOP_CONST_STRING_resolve: 691 movl rSELF,%eax 692 EXPORT_PC 693 movl offThread_method(%eax),%eax # eax<- self->method 694 movzwl 2(rPC),%ecx # ecx<- BBBB 695 movl offMethod_clazz(%eax),%eax 696 movl %ecx,OUT_ARG1(%esp) 697 movl %eax,OUT_ARG0(%esp) 698 SPILL(rIBASE) 699 call dvmResolveString # go resolve 700 UNSPILL(rIBASE) 701 testl %eax,%eax # failed? 702 je common_exceptionThrown 703 FETCH_INST_OPCODE 2 %ecx 704 SET_VREG %eax rINST 705 ADVANCE_PC 2 706 GOTO_NEXT_R %ecx 707 708/* ------------------------------ */ 709.L_OP_CONST_STRING_JUMBO: /* 0x1b */ 710/* File: x86/OP_CONST_STRING_JUMBO.S */ 711 712 /* const/string vAA, String@BBBBBBBB */ 713 movl rSELF,%ecx 714 movl 2(rPC),%eax # eax<- BBBBBBBB 715 movl offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex 716 movl offDvmDex_pResStrings(%ecx),%ecx # ecx<- dvmDex->pResStrings 717 movl (%ecx,%eax,4),%eax # eax<- rResString[BBBB] 718 FETCH_INST_OPCODE 3 %ecx 719 testl %eax,%eax # resolved yet? 720 je .LOP_CONST_STRING_JUMBO_resolve 721 SET_VREG %eax rINST # vAA<- rResString[BBBB] 722 ADVANCE_PC 3 723 GOTO_NEXT_R %ecx 724 725/* This is the less common path, so we'll redo some work 726 here rather than force spills on the common path */ 727.LOP_CONST_STRING_JUMBO_resolve: 728 movl rSELF,%eax 729 EXPORT_PC 730 movl offThread_method(%eax),%eax # eax<- self->method 731 movl 2(rPC),%ecx # ecx<- BBBBBBBB 732 movl offMethod_clazz(%eax),%eax 733 movl %ecx,OUT_ARG1(%esp) 734 movl %eax,OUT_ARG0(%esp) 735 SPILL(rIBASE) 736 call dvmResolveString # go resolve 737 UNSPILL(rIBASE) 738 testl %eax,%eax # failed? 739 je common_exceptionThrown 740 FETCH_INST_OPCODE 3 %ecx 741 SET_VREG %eax rINST 742 ADVANCE_PC 3 743 GOTO_NEXT_R %ecx 744 745/* ------------------------------ */ 746.L_OP_CONST_CLASS: /* 0x1c */ 747/* File: x86/OP_CONST_CLASS.S */ 748 749 /* const/class vAA, Class@BBBB */ 750 movl rSELF,%ecx 751 movzwl 2(rPC),%eax # eax<- BBBB 752 movl offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex 753 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- dvmDex->pResClasses 754 movl (%ecx,%eax,4),%eax # eax<- rResClasses[BBBB] 755 testl %eax,%eax # resolved yet? 756 je .LOP_CONST_CLASS_resolve 757 FETCH_INST_OPCODE 2 %ecx 758 SET_VREG %eax rINST # vAA<- rResClasses[BBBB] 759 ADVANCE_PC 2 760 GOTO_NEXT_R %ecx 761 762/* This is the less common path, so we'll redo some work 763 here rather than force spills on the common path */ 764.LOP_CONST_CLASS_resolve: 765 movl rSELF,%eax 766 EXPORT_PC 767 movl offThread_method(%eax),%eax # eax<- self->method 768 movl $1,OUT_ARG2(%esp) # true 769 movzwl 2(rPC),%ecx # ecx<- BBBB 770 movl offMethod_clazz(%eax),%eax 771 movl %ecx,OUT_ARG1(%esp) 772 movl %eax,OUT_ARG0(%esp) 773 SPILL(rIBASE) 774 call dvmResolveClass # go resolve 775 UNSPILL(rIBASE) 776 testl %eax,%eax # failed? 777 je common_exceptionThrown 778 FETCH_INST_OPCODE 2 %ecx 779 SET_VREG %eax rINST 780 ADVANCE_PC 2 781 GOTO_NEXT_R %ecx 782 783/* ------------------------------ */ 784.L_OP_MONITOR_ENTER: /* 0x1d */ 785/* File: x86/OP_MONITOR_ENTER.S */ 786 /* 787 * Synchronize on an object. 788 */ 789 /* monitor-enter vAA */ 790 movl rSELF,%ecx 791 GET_VREG_R %eax rINST # eax<- vAA 792 FETCH_INST_WORD 1 793 testl %eax,%eax # null object? 794 EXPORT_PC # need for precise GC 795 je common_errNullObject 796 movl %ecx,OUT_ARG0(%esp) 797 movl %eax,OUT_ARG1(%esp) 798 SPILL(rIBASE) 799 call dvmLockObject # dvmLockObject(self,object) 800 UNSPILL(rIBASE) 801 FETCH_INST_OPCODE 1 %ecx 802 ADVANCE_PC 1 803 GOTO_NEXT_R %ecx 804 805/* ------------------------------ */ 806.L_OP_MONITOR_EXIT: /* 0x1e */ 807/* File: x86/OP_MONITOR_EXIT.S */ 808 /* 809 * Unlock an object. 810 * 811 * Exceptions that occur when unlocking a monitor need to appear as 812 * if they happened at the following instruction. See the Dalvik 813 * instruction spec. 814 */ 815 /* monitor-exit vAA */ 816 GET_VREG_R %eax rINST 817 movl rSELF,%ecx 818 EXPORT_PC 819 testl %eax,%eax # null object? 820 je .LOP_MONITOR_EXIT_errNullObject # go if so 821 movl %eax,OUT_ARG1(%esp) 822 movl %ecx,OUT_ARG0(%esp) 823 SPILL(rIBASE) 824 call dvmUnlockObject # unlock(self,obj) 825 UNSPILL(rIBASE) 826 FETCH_INST_OPCODE 1 %ecx 827 testl %eax,%eax # success? 828 ADVANCE_PC 1 829 je common_exceptionThrown # no, exception pending 830 GOTO_NEXT_R %ecx 831.LOP_MONITOR_EXIT_errNullObject: 832 ADVANCE_PC 1 # advance before throw 833 jmp common_errNullObject 834 835/* ------------------------------ */ 836.L_OP_CHECK_CAST: /* 0x1f */ 837/* File: x86/OP_CHECK_CAST.S */ 838 /* 839 * Check to see if a cast from one class to another is allowed. 840 */ 841 /* check-cast vAA, class@BBBB */ 842 movl rSELF,%ecx 843 GET_VREG_R rINST,rINST # rINST<- vAA (object) 844 movzwl 2(rPC),%eax # eax<- BBBB 845 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 846 testl rINST,rINST # is oject null? 847 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 848 je .LOP_CHECK_CAST_okay # null obj, cast always succeeds 849 movl (%ecx,%eax,4),%eax # eax<- resolved class 850 movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz 851 testl %eax,%eax # have we resolved this before? 852 je .LOP_CHECK_CAST_resolve # no, go do it now 853.LOP_CHECK_CAST_resolved: 854 cmpl %eax,%ecx # same class (trivial success)? 855 jne .LOP_CHECK_CAST_fullcheck # no, do full check 856.LOP_CHECK_CAST_okay: 857 FETCH_INST_OPCODE 2 %ecx 858 ADVANCE_PC 2 859 GOTO_NEXT_R %ecx 860 861 /* 862 * Trivial test failed, need to perform full check. This is common. 863 * ecx holds obj->clazz 864 * eax holds class resolved from BBBB 865 * rINST holds object 866 */ 867.LOP_CHECK_CAST_fullcheck: 868 movl %eax,sReg0 # we'll need the desired class on failure 869 movl %eax,OUT_ARG1(%esp) 870 movl %ecx,OUT_ARG0(%esp) 871 SPILL(rIBASE) 872 call dvmInstanceofNonTrivial # eax<- boolean result 873 UNSPILL(rIBASE) 874 testl %eax,%eax # failed? 875 jne .LOP_CHECK_CAST_okay # no, success 876 877 # A cast has failed. We need to throw a ClassCastException. 878 EXPORT_PC 879 movl offObject_clazz(rINST),%eax 880 movl %eax,OUT_ARG0(%esp) # arg0<- obj->clazz 881 movl sReg0,%ecx 882 movl %ecx,OUT_ARG1(%esp) # arg1<- desired class 883 call dvmThrowClassCastException 884 jmp common_exceptionThrown 885 886 /* 887 * Resolution required. This is the least-likely path, and we're 888 * going to have to recreate some data. 889 * 890 * rINST holds object 891 */ 892.LOP_CHECK_CAST_resolve: 893 movl rSELF,%ecx 894 EXPORT_PC 895 movzwl 2(rPC),%eax # eax<- BBBB 896 movl offThread_method(%ecx),%ecx # ecx<- self->method 897 movl %eax,OUT_ARG1(%esp) # arg1<- BBBB 898 movl offMethod_clazz(%ecx),%ecx # ecx<- metho->clazz 899 movl $0,OUT_ARG2(%esp) # arg2<- false 900 movl %ecx,OUT_ARG0(%esp) # arg0<- method->clazz 901 SPILL(rIBASE) 902 call dvmResolveClass # eax<- resolved ClassObject ptr 903 UNSPILL(rIBASE) 904 testl %eax,%eax # got null? 905 je common_exceptionThrown # yes, handle exception 906 movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz 907 jmp .LOP_CHECK_CAST_resolved # pick up where we left off 908 909/* ------------------------------ */ 910.L_OP_INSTANCE_OF: /* 0x20 */ 911/* File: x86/OP_INSTANCE_OF.S */ 912 /* 913 * Check to see if an object reference is an instance of a class. 914 * 915 * Most common situation is a non-null object, being compared against 916 * an already-resolved class. 917 */ 918 /* instance-of vA, vB, class@CCCC */ 919 movl rINST,%eax # eax<- BA 920 sarl $4,%eax # eax<- B 921 GET_VREG_R %eax %eax # eax<- vB (obj) 922 movl rSELF,%ecx 923 testl %eax,%eax # object null? 924 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 925 SPILL(rIBASE) # preserve rIBASE 926 je .LOP_INSTANCE_OF_store # null obj, not instance, store it 927 movzwl 2(rPC),rIBASE # rIBASE<- CCCC 928 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 929 movl (%ecx,rIBASE,4),%ecx # ecx<- resolved class 930 movl offObject_clazz(%eax),%eax # eax<- obj->clazz 931 testl %ecx,%ecx # have we resolved this before? 932 je .LOP_INSTANCE_OF_resolve # not resolved, do it now 933.LOP_INSTANCE_OF_resolved: # eax<- obj->clazz, ecx<- resolved class 934 cmpl %eax,%ecx # same class (trivial success)? 935 je .LOP_INSTANCE_OF_trivial # yes, trivial finish 936 /* 937 * Trivial test failed, need to perform full check. This is common. 938 * eax holds obj->clazz 939 * ecx holds class resolved from BBBB 940 * rINST has BA 941 */ 942 movl %eax,OUT_ARG0(%esp) 943 movl %ecx,OUT_ARG1(%esp) 944 call dvmInstanceofNonTrivial # eax<- boolean result 945 # fall through to OP_INSTANCE_OF_store 946 947 /* 948 * eax holds boolean result 949 * rINST holds BA 950 */ 951.LOP_INSTANCE_OF_store: 952 FETCH_INST_OPCODE 2 %ecx 953 UNSPILL(rIBASE) 954 andb $0xf,rINSTbl # <- A 955 ADVANCE_PC 2 956 SET_VREG %eax rINST # vA<- eax 957 GOTO_NEXT_R %ecx 958 959 /* 960 * Trivial test succeeded, save and bail. 961 * r9 holds A 962 */ 963.LOP_INSTANCE_OF_trivial: 964 FETCH_INST_OPCODE 2 %ecx 965 UNSPILL(rIBASE) 966 andb $0xf,rINSTbl # <- A 967 ADVANCE_PC 2 968 movl $1,%eax 969 SET_VREG %eax rINST # vA<- true 970 GOTO_NEXT_R %ecx 971 972 /* 973 * Resolution required. This is the least-likely path. 974 * 975 * rIBASE holds BBBB 976 * rINST holds BA 977 */ 978.LOP_INSTANCE_OF_resolve: 979 movl rIBASE,OUT_ARG1(%esp) # arg1<- BBBB 980 movl rSELF,%ecx 981 movl offThread_method(%ecx),%ecx 982 movl $1,OUT_ARG2(%esp) # arg2<- true 983 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 984 EXPORT_PC 985 movl %ecx,OUT_ARG0(%esp) # arg0<- method->clazz 986 call dvmResolveClass # eax<- resolved ClassObject ptr 987 testl %eax,%eax # success? 988 je common_exceptionThrown # no, handle exception 989/* Now, we need to sync up with fast path. We need eax to 990 * hold the obj->clazz, and ecx to hold the resolved class 991 */ 992 movl %eax,%ecx # ecx<- resolved class 993 movl rINST,%eax # eax<- BA 994 sarl $4,%eax # eax<- B 995 GET_VREG_R %eax %eax # eax<- vB (obj) 996 movl offObject_clazz(%eax),%eax # eax<- obj->clazz 997 jmp .LOP_INSTANCE_OF_resolved 998 999/* ------------------------------ */ 1000.L_OP_ARRAY_LENGTH: /* 0x21 */ 1001/* File: x86/OP_ARRAY_LENGTH.S */ 1002 /* 1003 * Return the length of an array. 1004 */ 1005 mov rINST,%eax # eax<- BA 1006 sarl $4,rINST # rINST<- B 1007 GET_VREG_R %ecx rINST # ecx<- vB (object ref) 1008 andb $0xf,%al # eax<- A 1009 testl %ecx,%ecx # is null? 1010 je common_errNullObject 1011 movl offArrayObject_length(%ecx),rINST 1012 FETCH_INST_OPCODE 1 %ecx 1013 ADVANCE_PC 1 1014 SET_VREG rINST %eax 1015 GOTO_NEXT_R %ecx 1016 1017/* ------------------------------ */ 1018.L_OP_NEW_INSTANCE: /* 0x22 */ 1019/* File: x86/OP_NEW_INSTANCE.S */ 1020 /* 1021 * Create a new instance of a class. 1022 */ 1023 /* new-instance vAA, class@BBBB */ 1024 movl rSELF,%ecx 1025 movzwl 2(rPC),%eax # eax<- BBBB 1026 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 1027 SPILL(rIBASE) 1028 SPILL_TMP2(%ebx) 1029 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 1030 EXPORT_PC 1031#if defined(WITH_JIT) 1032 lea (%ecx,%eax,4),%ebx # ebx <- &resolved class 1033#endif 1034 movl (%ecx,%eax,4),%ecx # ecx<- resolved class 1035 testl %ecx,%ecx # resolved? 1036 je .LOP_NEW_INSTANCE_resolve # no, go do it 1037.LOP_NEW_INSTANCE_resolved: # on entry, ecx<- class 1038 cmpb $CLASS_INITIALIZED,offClassObject_status(%ecx) 1039 jne .LOP_NEW_INSTANCE_needinit 1040.LOP_NEW_INSTANCE_initialized: # on entry, ecx<- class 1041 movl $ALLOC_DONT_TRACK,OUT_ARG1(%esp) 1042 movl %ecx,OUT_ARG0(%esp) 1043 call dvmAllocObject # eax<- new object 1044 testl %eax,%eax # success? 1045 je common_exceptionThrown # no, bail out 1046#if defined(WITH_JIT) 1047 /* 1048 * The JIT needs the class to be fully resolved before it can 1049 * include this instruction in a trace. 1050 */ 1051 movl rSELF, %ecx 1052 movl offThread_subMode(%ecx), %ecx 1053 andl $kSubModeJitTraceBuild, %ecx # under construction? 1054 jne .LOP_NEW_INSTANCE_jitCheck 1055#endif 1056.LOP_NEW_INSTANCE_end: 1057 UNSPILL_TMP2(%ebx) 1058 SET_VREG %eax rINST 1059 UNSPILL(rIBASE) 1060 FETCH_INST_OPCODE 2 %ecx 1061 ADVANCE_PC 2 1062 GOTO_NEXT_R %ecx 1063 1064#if defined(WITH_JIT) 1065 /* 1066 * Check to see if we need to stop the trace building early. 1067 * eax: new object 1068 */ 1069.LOP_NEW_INSTANCE_jitCheck: 1070 cmp $0, (%ebx) # okay? 1071 jne .LOP_NEW_INSTANCE_end # yes, finish 1072 SPILL_TMP1(%eax) # preserve new object 1073 movl rSELF, %ecx 1074 movl %ecx, OUT_ARG0(%esp) 1075 movl rPC, OUT_ARG1(%esp) 1076 call dvmJitEndTraceSelect # (self, pc) 1077 UNSPILL_TMP1(%eax) 1078 UNSPILL_TMP2(%ebx) 1079 SET_VREG %eax rINST # vAA <- new object 1080 UNSPILL(rIBASE) 1081 FETCH_INST_OPCODE 2 %ecx 1082 ADVANCE_PC 2 1083 GOTO_NEXT_R %ecx 1084#endif 1085 1086 /* 1087 * Class initialization required. 1088 * 1089 * ecx holds class object 1090 */ 1091.LOP_NEW_INSTANCE_needinit: 1092 SPILL_TMP1(%ecx) # save object 1093 movl %ecx,OUT_ARG0(%esp) 1094 call dvmInitClass # initialize class 1095 UNSPILL_TMP1(%ecx) # restore object 1096 testl %eax,%eax # success? 1097 jne .LOP_NEW_INSTANCE_initialized # success, continue 1098 jmp common_exceptionThrown # go deal with init exception 1099 1100 /* 1101 * Resolution required. This is the least-likely path. 1102 * 1103 */ 1104.LOP_NEW_INSTANCE_resolve: 1105 movl rSELF,%ecx 1106 movzwl 2(rPC),%eax 1107 movl offThread_method(%ecx),%ecx # ecx<- self->method 1108 movl %eax,OUT_ARG1(%esp) 1109 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 1110 movl $0,OUT_ARG2(%esp) 1111 movl %ecx,OUT_ARG0(%esp) 1112 call dvmResolveClass # call(clazz,off,flags) 1113 movl %eax,%ecx # ecx<- resolved ClassObject ptr 1114 testl %ecx,%ecx # success? 1115 jne .LOP_NEW_INSTANCE_resolved # good to go 1116 jmp common_exceptionThrown # no, handle exception 1117 1118/* ------------------------------ */ 1119.L_OP_NEW_ARRAY: /* 0x23 */ 1120/* File: x86/OP_NEW_ARRAY.S */ 1121 /* 1122 * Allocate an array of objects, specified with the array class 1123 * and a count. 1124 * 1125 * The verifier guarantees that this is an array class, so we don't 1126 * check for it here. 1127 */ 1128 /* new-array vA, vB, class@CCCC */ 1129 movl rSELF,%ecx 1130 EXPORT_PC 1131 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 1132 movzwl 2(rPC),%eax # eax<- CCCC 1133 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 1134 SPILL(rIBASE) 1135 movl (%ecx,%eax,4),%ecx # ecx<- resolved class 1136 movzbl rINSTbl,%eax 1137 sarl $4,%eax # eax<- B 1138 GET_VREG_R %eax %eax # eax<- vB (array length) 1139 andb $0xf,rINSTbl # rINST<- A 1140 testl %eax,%eax 1141 js common_errNegativeArraySize # bail, passing len in eax 1142 testl %ecx,%ecx # already resolved? 1143 jne .LOP_NEW_ARRAY_finish # yes, fast path 1144 /* 1145 * Resolve class. (This is an uncommon case.) 1146 * ecx holds class (null here) 1147 * eax holds array length (vB) 1148 */ 1149 movl rSELF,%ecx 1150 SPILL_TMP1(%eax) # save array length 1151 movl offThread_method(%ecx),%ecx # ecx<- self->method 1152 movzwl 2(rPC),%eax # eax<- CCCC 1153 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 1154 movl %eax,OUT_ARG1(%esp) 1155 movl $0,OUT_ARG2(%esp) 1156 movl %ecx,OUT_ARG0(%esp) 1157 call dvmResolveClass # eax<- call(clazz,ref,flag) 1158 movl %eax,%ecx 1159 UNSPILL_TMP1(%eax) 1160 testl %ecx,%ecx # successful resolution? 1161 je common_exceptionThrown # no, bail. 1162# fall through to OP_NEW_ARRAY_finish 1163 1164 /* 1165 * Finish allocation 1166 * 1167 * ecx holds class 1168 * eax holds array length (vB) 1169 */ 1170.LOP_NEW_ARRAY_finish: 1171 movl %ecx,OUT_ARG0(%esp) 1172 movl %eax,OUT_ARG1(%esp) 1173 movl $ALLOC_DONT_TRACK,OUT_ARG2(%esp) 1174 call dvmAllocArrayByClass # eax<- call(clazz,length,flags) 1175 FETCH_INST_OPCODE 2 %ecx 1176 UNSPILL(rIBASE) 1177 testl %eax,%eax # failed? 1178 je common_exceptionThrown # yup - go handle 1179 SET_VREG %eax rINST 1180 ADVANCE_PC 2 1181 GOTO_NEXT_R %ecx 1182 1183/* ------------------------------ */ 1184.L_OP_FILLED_NEW_ARRAY: /* 0x24 */ 1185/* File: x86/OP_FILLED_NEW_ARRAY.S */ 1186 /* 1187 * Create a new array with elements filled from registers. 1188 * 1189 * for: filled-new-array, filled-new-array/range 1190 */ 1191 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1192 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1193 movl rSELF,%eax 1194 movl offThread_methodClassDex(%eax),%eax # eax<- pDvmDex 1195 movzwl 2(rPC),%ecx # ecx<- BBBB 1196 movl offDvmDex_pResClasses(%eax),%eax # eax<- pDvmDex->pResClasses 1197 SPILL(rIBASE) # preserve rIBASE 1198 movl (%eax,%ecx,4),%eax # eax<- resolved class 1199 EXPORT_PC 1200 testl %eax,%eax # already resolved? 1201 jne .LOP_FILLED_NEW_ARRAY_continue # yes, continue 1202 # less frequent path, so we'll redo some work 1203 movl rSELF,%eax 1204 movl $0,OUT_ARG2(%esp) # arg2<- false 1205 movl %ecx,OUT_ARG1(%esp) # arg1<- BBBB 1206 movl offThread_method(%eax),%eax # eax<- self->method 1207 movl offMethod_clazz(%eax),%eax # eax<- method->clazz 1208 movl %eax,OUT_ARG0(%esp) # arg0<- clazz 1209 call dvmResolveClass # eax<- call(clazz,ref,flag) 1210 testl %eax,%eax # null? 1211 je common_exceptionThrown # yes, handle it 1212 1213 # note: fall through to .LOP_FILLED_NEW_ARRAY_continue 1214 1215 /* 1216 * On entry: 1217 * eax holds array class [r0] 1218 * rINST holds AA or BB [r10] 1219 * ecx is scratch 1220 */ 1221.LOP_FILLED_NEW_ARRAY_continue: 1222 movl offClassObject_descriptor(%eax),%ecx # ecx<- arrayClass->descriptor 1223 movl $ALLOC_DONT_TRACK,OUT_ARG2(%esp) # arg2<- flags 1224 movzbl 1(%ecx),%ecx # ecx<- descriptor[1] 1225 movl %eax,OUT_ARG0(%esp) # arg0<- arrayClass 1226 movl rSELF,%eax 1227 cmpb $'I',%cl # supported? 1228 je 1f 1229 cmpb $'L',%cl 1230 je 1f 1231 cmpb $'[',%cl 1232 jne .LOP_FILLED_NEW_ARRAY_notimpl # no, not handled yet 12331: 1234 movl %ecx,offThread_retval+4(%eax) # save type 1235 .if (!0) 1236 SPILL_TMP1(rINST) # save copy, need "B" later 1237 sarl $4,rINST 1238 .endif 1239 movl rINST,OUT_ARG1(%esp) # arg1<- A or AA (length) 1240 call dvmAllocArrayByClass # eax<- call(arrayClass, length, flags) 1241 movl rSELF,%ecx 1242 testl %eax,%eax # alloc successful? 1243 je common_exceptionThrown # no, handle exception 1244 movl %eax,offThread_retval(%ecx) # retval.l<- new array 1245 movzwl 4(rPC),%ecx # ecx<- FEDC or CCCC 1246 leal offArrayObject_contents(%eax),%eax # eax<- newArray->contents 1247 1248/* at this point: 1249 * eax is pointer to tgt 1250 * rINST is length 1251 * ecx is FEDC or CCCC 1252 * TMP_SPILL1 is BA 1253 * We now need to copy values from registers into the array 1254 */ 1255 1256 .if 0 1257 # set up src pointer 1258 SPILL_TMP2(%esi) 1259 SPILL_TMP3(%edi) 1260 leal (rFP,%ecx,4),%esi # set up src ptr 1261 movl %eax,%edi # set up dst ptr 1262 movl rINST,%ecx # load count register 1263 rep 1264 movsd 1265 UNSPILL_TMP2(%esi) 1266 UNSPILL_TMP3(%edi) 1267 movl rSELF,%ecx 1268 movl offThread_retval+4(%ecx),%eax # eax<- type 1269 .else 1270 testl rINST,rINST 1271 je 4f 1272 UNSPILL_TMP1(rIBASE) # restore "BA" 1273 andl $0x0f,rIBASE # rIBASE<- 0000000A 1274 sall $16,rIBASE # rIBASE<- 000A0000 1275 orl %ecx,rIBASE # rIBASE<- 000AFEDC 12763: 1277 movl $0xf,%ecx 1278 andl rIBASE,%ecx # ecx<- next reg to load 1279 GET_VREG_R %ecx %ecx 1280 shrl $4,rIBASE 1281 leal 4(%eax),%eax 1282 movl %ecx,-4(%eax) 1283 sub $1,rINST 1284 jne 3b 12854: 1286 movl rSELF,%ecx 1287 movl offThread_retval+4(%ecx),%eax # eax<- type 1288 .endif 1289 1290 cmpb $'I',%al # Int array? 1291 je 5f # skip card mark if so 1292 movl offThread_retval(%ecx),%eax # eax<- object head 1293 movl offThread_cardTable(%ecx),%ecx # card table base 1294 shrl $GC_CARD_SHIFT,%eax # convert to card num 1295 movb %cl,(%ecx,%eax) # mark card based on object head 12965: 1297 UNSPILL(rIBASE) # restore rIBASE 1298 FETCH_INST_OPCODE 3 %ecx 1299 ADVANCE_PC 3 1300 GOTO_NEXT_R %ecx 1301 1302 1303 /* 1304 * Throw an exception indicating that we have not implemented this 1305 * mode of filled-new-array. 1306 */ 1307.LOP_FILLED_NEW_ARRAY_notimpl: 1308 movl $.LstrFilledNewArrayNotImplA,%eax 1309 movl %eax,OUT_ARG0(%esp) 1310 call dvmThrowInternalError 1311 jmp common_exceptionThrown 1312 1313/* ------------------------------ */ 1314.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 1315/* File: x86/OP_FILLED_NEW_ARRAY_RANGE.S */ 1316/* File: x86/OP_FILLED_NEW_ARRAY.S */ 1317 /* 1318 * Create a new array with elements filled from registers. 1319 * 1320 * for: filled-new-array, filled-new-array/range 1321 */ 1322 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1323 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1324 movl rSELF,%eax 1325 movl offThread_methodClassDex(%eax),%eax # eax<- pDvmDex 1326 movzwl 2(rPC),%ecx # ecx<- BBBB 1327 movl offDvmDex_pResClasses(%eax),%eax # eax<- pDvmDex->pResClasses 1328 SPILL(rIBASE) # preserve rIBASE 1329 movl (%eax,%ecx,4),%eax # eax<- resolved class 1330 EXPORT_PC 1331 testl %eax,%eax # already resolved? 1332 jne .LOP_FILLED_NEW_ARRAY_RANGE_continue # yes, continue 1333 # less frequent path, so we'll redo some work 1334 movl rSELF,%eax 1335 movl $0,OUT_ARG2(%esp) # arg2<- false 1336 movl %ecx,OUT_ARG1(%esp) # arg1<- BBBB 1337 movl offThread_method(%eax),%eax # eax<- self->method 1338 movl offMethod_clazz(%eax),%eax # eax<- method->clazz 1339 movl %eax,OUT_ARG0(%esp) # arg0<- clazz 1340 call dvmResolveClass # eax<- call(clazz,ref,flag) 1341 testl %eax,%eax # null? 1342 je common_exceptionThrown # yes, handle it 1343 1344 # note: fall through to .LOP_FILLED_NEW_ARRAY_RANGE_continue 1345 1346 /* 1347 * On entry: 1348 * eax holds array class [r0] 1349 * rINST holds AA or BB [r10] 1350 * ecx is scratch 1351 */ 1352.LOP_FILLED_NEW_ARRAY_RANGE_continue: 1353 movl offClassObject_descriptor(%eax),%ecx # ecx<- arrayClass->descriptor 1354 movl $ALLOC_DONT_TRACK,OUT_ARG2(%esp) # arg2<- flags 1355 movzbl 1(%ecx),%ecx # ecx<- descriptor[1] 1356 movl %eax,OUT_ARG0(%esp) # arg0<- arrayClass 1357 movl rSELF,%eax 1358 cmpb $'I',%cl # supported? 1359 je 1f 1360 cmpb $'L',%cl 1361 je 1f 1362 cmpb $'[',%cl 1363 jne .LOP_FILLED_NEW_ARRAY_RANGE_notimpl # no, not handled yet 13641: 1365 movl %ecx,offThread_retval+4(%eax) # save type 1366 .if (!1) 1367 SPILL_TMP1(rINST) # save copy, need "B" later 1368 sarl $4,rINST 1369 .endif 1370 movl rINST,OUT_ARG1(%esp) # arg1<- A or AA (length) 1371 call dvmAllocArrayByClass # eax<- call(arrayClass, length, flags) 1372 movl rSELF,%ecx 1373 testl %eax,%eax # alloc successful? 1374 je common_exceptionThrown # no, handle exception 1375 movl %eax,offThread_retval(%ecx) # retval.l<- new array 1376 movzwl 4(rPC),%ecx # ecx<- FEDC or CCCC 1377 leal offArrayObject_contents(%eax),%eax # eax<- newArray->contents 1378 1379/* at this point: 1380 * eax is pointer to tgt 1381 * rINST is length 1382 * ecx is FEDC or CCCC 1383 * TMP_SPILL1 is BA 1384 * We now need to copy values from registers into the array 1385 */ 1386 1387 .if 1 1388 # set up src pointer 1389 SPILL_TMP2(%esi) 1390 SPILL_TMP3(%edi) 1391 leal (rFP,%ecx,4),%esi # set up src ptr 1392 movl %eax,%edi # set up dst ptr 1393 movl rINST,%ecx # load count register 1394 rep 1395 movsd 1396 UNSPILL_TMP2(%esi) 1397 UNSPILL_TMP3(%edi) 1398 movl rSELF,%ecx 1399 movl offThread_retval+4(%ecx),%eax # eax<- type 1400 .else 1401 testl rINST,rINST 1402 je 4f 1403 UNSPILL_TMP1(rIBASE) # restore "BA" 1404 andl $0x0f,rIBASE # rIBASE<- 0000000A 1405 sall $16,rIBASE # rIBASE<- 000A0000 1406 orl %ecx,rIBASE # rIBASE<- 000AFEDC 14073: 1408 movl $0xf,%ecx 1409 andl rIBASE,%ecx # ecx<- next reg to load 1410 GET_VREG_R %ecx %ecx 1411 shrl $4,rIBASE 1412 leal 4(%eax),%eax 1413 movl %ecx,-4(%eax) 1414 sub $1,rINST 1415 jne 3b 14164: 1417 movl rSELF,%ecx 1418 movl offThread_retval+4(%ecx),%eax # eax<- type 1419 .endif 1420 1421 cmpb $'I',%al # Int array? 1422 je 5f # skip card mark if so 1423 movl offThread_retval(%ecx),%eax # eax<- object head 1424 movl offThread_cardTable(%ecx),%ecx # card table base 1425 shrl $GC_CARD_SHIFT,%eax # convert to card num 1426 movb %cl,(%ecx,%eax) # mark card based on object head 14275: 1428 UNSPILL(rIBASE) # restore rIBASE 1429 FETCH_INST_OPCODE 3 %ecx 1430 ADVANCE_PC 3 1431 GOTO_NEXT_R %ecx 1432 1433 1434 /* 1435 * Throw an exception indicating that we have not implemented this 1436 * mode of filled-new-array. 1437 */ 1438.LOP_FILLED_NEW_ARRAY_RANGE_notimpl: 1439 movl $.LstrFilledNewArrayNotImplA,%eax 1440 movl %eax,OUT_ARG0(%esp) 1441 call dvmThrowInternalError 1442 jmp common_exceptionThrown 1443 1444 1445/* ------------------------------ */ 1446.L_OP_FILL_ARRAY_DATA: /* 0x26 */ 1447/* File: x86/OP_FILL_ARRAY_DATA.S */ 1448 /* fill-array-data vAA, +BBBBBBBB */ 1449 movl 2(rPC),%ecx # ecx<- BBBBbbbb 1450 leal (rPC,%ecx,2),%ecx # ecx<- PC + BBBBbbbb*2 1451 GET_VREG_R %eax rINST 1452 EXPORT_PC 1453 movl %eax,OUT_ARG0(%esp) 1454 movl %ecx,OUT_ARG1(%esp) 1455 SPILL(rIBASE) 1456 call dvmInterpHandleFillArrayData 1457 UNSPILL(rIBASE) 1458 FETCH_INST_OPCODE 3 %ecx 1459 testl %eax,%eax # exception thrown? 1460 je common_exceptionThrown 1461 ADVANCE_PC 3 1462 GOTO_NEXT_R %ecx 1463 1464/* ------------------------------ */ 1465.L_OP_THROW: /* 0x27 */ 1466/* File: x86/OP_THROW.S */ 1467 /* 1468 * Throw an exception object in the current thread. 1469 */ 1470 /* throw vAA */ 1471 EXPORT_PC 1472 GET_VREG_R %eax rINST # eax<- exception object 1473 movl rSELF,%ecx # ecx<- self 1474 testl %eax,%eax # null object? 1475 je common_errNullObject 1476 movl %eax,offThread_exception(%ecx) # thread->exception<- obj 1477 jmp common_exceptionThrown 1478 1479/* ------------------------------ */ 1480.L_OP_GOTO: /* 0x28 */ 1481/* File: x86/OP_GOTO.S */ 1482 /* 1483 * Unconditional branch, 8-bit offset. 1484 * 1485 * The branch distance is a signed code-unit offset, which we need to 1486 * double to get a byte offset. 1487 */ 1488 /* goto +AA */ 1489 movl rSELF,%ecx 1490 movsbl rINSTbl,%eax # eax<- ssssssAA 1491 movl offThread_curHandlerTable(%ecx),rIBASE 1492 FETCH_INST_INDEXED %eax 1493 ADVANCE_PC_INDEXED %eax 1494#if defined(WITH_JIT) 1495 GET_JIT_PROF_TABLE %ecx %eax 1496 cmp $0, %eax 1497 jne common_updateProfile # set up %ebx & %edx & rPC 1498#endif 1499 GOTO_NEXT 1500 1501/* ------------------------------ */ 1502.L_OP_GOTO_16: /* 0x29 */ 1503/* File: x86/OP_GOTO_16.S */ 1504 /* 1505 * Unconditional branch, 16-bit offset. 1506 * 1507 * The branch distance is a signed code-unit offset 1508 */ 1509 /* goto/16 +AAAA */ 1510 movl rSELF,%ecx 1511 movswl 2(rPC),%eax # eax<- ssssAAAA 1512 movl offThread_curHandlerTable(%ecx),rIBASE 1513 FETCH_INST_INDEXED %eax 1514 ADVANCE_PC_INDEXED %eax 1515#if defined(WITH_JIT) 1516 GET_JIT_PROF_TABLE %ecx %eax 1517 cmp $0, %eax 1518 jne common_updateProfile # set up %ebx & %edx & rPC 1519#endif 1520 GOTO_NEXT 1521 1522/* ------------------------------ */ 1523.L_OP_GOTO_32: /* 0x2a */ 1524/* File: x86/OP_GOTO_32.S */ 1525 /* 1526 * Unconditional branch, 32-bit offset. 1527 * 1528 * The branch distance is a signed code-unit offset. 1529 */ 1530 /* goto/32 AAAAAAAA */ 1531 movl rSELF,%ecx 1532 movl 2(rPC),%eax # eax<- AAAAAAAA 1533 movl offThread_curHandlerTable(%ecx),rIBASE 1534 FETCH_INST_INDEXED %eax 1535 ADVANCE_PC_INDEXED %eax 1536#if defined(WITH_JIT) 1537 GET_JIT_PROF_TABLE %ecx %eax 1538 cmp $0, %eax 1539 jne common_updateProfile # set up %ebx & %edx & rPC 1540#endif 1541 GOTO_NEXT 1542 1543/* ------------------------------ */ 1544.L_OP_PACKED_SWITCH: /* 0x2b */ 1545/* File: x86/OP_PACKED_SWITCH.S */ 1546 /* 1547 * Handle a packed-switch or sparse-switch instruction. In both cases 1548 * we decode it and hand it off to a helper function. 1549 * 1550 * We don't really expect backward branches in a switch statement, but 1551 * they're perfectly legal, so we check for them here. 1552 * 1553 * for: packed-switch, sparse-switch 1554 */ 1555 /* op vAA, +BBBB */ 1556 movl 2(rPC),%ecx # ecx<- BBBBbbbb 1557 GET_VREG_R %eax rINST # eax<- vAA 1558 leal (rPC,%ecx,2),%ecx # ecx<- PC + BBBBbbbb*2 1559 movl %eax,OUT_ARG1(%esp) # ARG1<- vAA 1560 movl %ecx,OUT_ARG0(%esp) # ARG0<- switchData 1561 call dvmInterpHandlePackedSwitch 1562 movl rSELF,%ecx 1563 ADVANCE_PC_INDEXED %eax 1564 movl offThread_curHandlerTable(%ecx),rIBASE 1565 FETCH_INST 1566#if defined(WITH_JIT) 1567 GET_JIT_PROF_TABLE %ecx %eax 1568 cmp $0, %eax 1569 jne common_updateProfile # set up %ebx & %edx & rPC 1570#endif 1571 GOTO_NEXT 1572 1573/* ------------------------------ */ 1574.L_OP_SPARSE_SWITCH: /* 0x2c */ 1575/* File: x86/OP_SPARSE_SWITCH.S */ 1576/* File: x86/OP_PACKED_SWITCH.S */ 1577 /* 1578 * Handle a packed-switch or sparse-switch instruction. In both cases 1579 * we decode it and hand it off to a helper function. 1580 * 1581 * We don't really expect backward branches in a switch statement, but 1582 * they're perfectly legal, so we check for them here. 1583 * 1584 * for: packed-switch, sparse-switch 1585 */ 1586 /* op vAA, +BBBB */ 1587 movl 2(rPC),%ecx # ecx<- BBBBbbbb 1588 GET_VREG_R %eax rINST # eax<- vAA 1589 leal (rPC,%ecx,2),%ecx # ecx<- PC + BBBBbbbb*2 1590 movl %eax,OUT_ARG1(%esp) # ARG1<- vAA 1591 movl %ecx,OUT_ARG0(%esp) # ARG0<- switchData 1592 call dvmInterpHandleSparseSwitch 1593 movl rSELF,%ecx 1594 ADVANCE_PC_INDEXED %eax 1595 movl offThread_curHandlerTable(%ecx),rIBASE 1596 FETCH_INST 1597#if defined(WITH_JIT) 1598 GET_JIT_PROF_TABLE %ecx %eax 1599 cmp $0, %eax 1600 jne common_updateProfile # set up %ebx & %edx & rPC 1601#endif 1602 GOTO_NEXT 1603 1604 1605/* ------------------------------ */ 1606.L_OP_CMPL_FLOAT: /* 0x2d */ 1607/* File: x86/OP_CMPL_FLOAT.S */ 1608/* File: x86/OP_CMPG_DOUBLE.S */ 1609 /* float/double_cmp[gl] vAA, vBB, vCC */ 1610 movzbl 3(rPC),%eax # eax<- CC 1611 movzbl 2(rPC),%ecx # ecx<- BB 1612 .if 0 1613 fldl (rFP,%eax,4) 1614 fldl (rFP,%ecx,4) 1615 .else 1616 flds (rFP,%eax,4) 1617 flds (rFP,%ecx,4) 1618 .endif 1619 xorl %ecx,%ecx 1620 fucompp # z if equal, p set if NaN, c set if st0 < st1 1621 fnstsw %ax 1622 sahf 1623 FETCH_INST_OPCODE 2 %eax 1624 jp .LOP_CMPL_FLOAT_isNaN 1625 je .LOP_CMPL_FLOAT_finish 1626 sbbl %ecx,%ecx 1627 jb .LOP_CMPL_FLOAT_finish 1628 incl %ecx 1629.LOP_CMPL_FLOAT_finish: 1630 SET_VREG %ecx rINST 1631 ADVANCE_PC 2 1632 GOTO_NEXT_R %eax 1633 1634.LOP_CMPL_FLOAT_isNaN: 1635 movl $-1,%ecx 1636 jmp .LOP_CMPL_FLOAT_finish 1637 1638 1639/* ------------------------------ */ 1640.L_OP_CMPG_FLOAT: /* 0x2e */ 1641/* File: x86/OP_CMPG_FLOAT.S */ 1642/* File: x86/OP_CMPG_DOUBLE.S */ 1643 /* float/double_cmp[gl] vAA, vBB, vCC */ 1644 movzbl 3(rPC),%eax # eax<- CC 1645 movzbl 2(rPC),%ecx # ecx<- BB 1646 .if 0 1647 fldl (rFP,%eax,4) 1648 fldl (rFP,%ecx,4) 1649 .else 1650 flds (rFP,%eax,4) 1651 flds (rFP,%ecx,4) 1652 .endif 1653 xorl %ecx,%ecx 1654 fucompp # z if equal, p set if NaN, c set if st0 < st1 1655 fnstsw %ax 1656 sahf 1657 FETCH_INST_OPCODE 2 %eax 1658 jp .LOP_CMPG_FLOAT_isNaN 1659 je .LOP_CMPG_FLOAT_finish 1660 sbbl %ecx,%ecx 1661 jb .LOP_CMPG_FLOAT_finish 1662 incl %ecx 1663.LOP_CMPG_FLOAT_finish: 1664 SET_VREG %ecx rINST 1665 ADVANCE_PC 2 1666 GOTO_NEXT_R %eax 1667 1668.LOP_CMPG_FLOAT_isNaN: 1669 movl $1,%ecx 1670 jmp .LOP_CMPG_FLOAT_finish 1671 1672 1673/* ------------------------------ */ 1674.L_OP_CMPL_DOUBLE: /* 0x2f */ 1675/* File: x86/OP_CMPL_DOUBLE.S */ 1676/* File: x86/OP_CMPG_DOUBLE.S */ 1677 /* float/double_cmp[gl] vAA, vBB, vCC */ 1678 movzbl 3(rPC),%eax # eax<- CC 1679 movzbl 2(rPC),%ecx # ecx<- BB 1680 .if 1 1681 fldl (rFP,%eax,4) 1682 fldl (rFP,%ecx,4) 1683 .else 1684 flds (rFP,%eax,4) 1685 flds (rFP,%ecx,4) 1686 .endif 1687 xorl %ecx,%ecx 1688 fucompp # z if equal, p set if NaN, c set if st0 < st1 1689 fnstsw %ax 1690 sahf 1691 FETCH_INST_OPCODE 2 %eax 1692 jp .LOP_CMPL_DOUBLE_isNaN 1693 je .LOP_CMPL_DOUBLE_finish 1694 sbbl %ecx,%ecx 1695 jb .LOP_CMPL_DOUBLE_finish 1696 incl %ecx 1697.LOP_CMPL_DOUBLE_finish: 1698 SET_VREG %ecx rINST 1699 ADVANCE_PC 2 1700 GOTO_NEXT_R %eax 1701 1702.LOP_CMPL_DOUBLE_isNaN: 1703 movl $-1,%ecx 1704 jmp .LOP_CMPL_DOUBLE_finish 1705 1706 1707/* ------------------------------ */ 1708.L_OP_CMPG_DOUBLE: /* 0x30 */ 1709/* File: x86/OP_CMPG_DOUBLE.S */ 1710 /* float/double_cmp[gl] vAA, vBB, vCC */ 1711 movzbl 3(rPC),%eax # eax<- CC 1712 movzbl 2(rPC),%ecx # ecx<- BB 1713 .if 1 1714 fldl (rFP,%eax,4) 1715 fldl (rFP,%ecx,4) 1716 .else 1717 flds (rFP,%eax,4) 1718 flds (rFP,%ecx,4) 1719 .endif 1720 xorl %ecx,%ecx 1721 fucompp # z if equal, p set if NaN, c set if st0 < st1 1722 fnstsw %ax 1723 sahf 1724 FETCH_INST_OPCODE 2 %eax 1725 jp .LOP_CMPG_DOUBLE_isNaN 1726 je .LOP_CMPG_DOUBLE_finish 1727 sbbl %ecx,%ecx 1728 jb .LOP_CMPG_DOUBLE_finish 1729 incl %ecx 1730.LOP_CMPG_DOUBLE_finish: 1731 SET_VREG %ecx rINST 1732 ADVANCE_PC 2 1733 GOTO_NEXT_R %eax 1734 1735.LOP_CMPG_DOUBLE_isNaN: 1736 movl $1,%ecx 1737 jmp .LOP_CMPG_DOUBLE_finish 1738 1739/* ------------------------------ */ 1740.L_OP_CMP_LONG: /* 0x31 */ 1741/* File: x86/OP_CMP_LONG.S */ 1742 /* 1743 * Compare two 64-bit values. Puts 0, 1, or -1 into the destination 1744 * register based on the results of the comparison. 1745 */ 1746 // TUNING: rework to avoid rIBASE spill 1747 /* cmp-long vAA, vBB, vCC */ 1748 movzbl 2(rPC),%ecx # ecx<- BB 1749 SPILL(rIBASE) 1750 movzbl 3(rPC),rIBASE # rIBASE- CC 1751 GET_VREG_WORD %eax %ecx,1 # eax<- v[BB+1] 1752 GET_VREG_WORD %ecx %ecx 0 # ecx<- v[BB+0] 1753 cmpl 4(rFP,rIBASE,4),%eax 1754 jl .LOP_CMP_LONG_smaller 1755 jg .LOP_CMP_LONG_bigger 1756 sub (rFP,rIBASE,4),%ecx 1757 ja .LOP_CMP_LONG_bigger 1758 jb .LOP_CMP_LONG_smaller 1759 SET_VREG %ecx rINST 1760 FETCH_INST_OPCODE 2 %ecx 1761 UNSPILL(rIBASE) 1762 ADVANCE_PC 2 1763 GOTO_NEXT_R %ecx 1764 1765.LOP_CMP_LONG_bigger: 1766 movl $1,%ecx 1767 SET_VREG %ecx rINST 1768 FETCH_INST_OPCODE 2 %ecx 1769 UNSPILL(rIBASE) 1770 ADVANCE_PC 2 1771 GOTO_NEXT_R %ecx 1772 1773.LOP_CMP_LONG_smaller: 1774 movl $-1,%ecx 1775 SET_VREG %ecx rINST 1776 FETCH_INST_OPCODE 2 %ecx 1777 UNSPILL(rIBASE) 1778 ADVANCE_PC 2 1779 GOTO_NEXT_R %ecx 1780 1781/* ------------------------------ */ 1782.L_OP_IF_EQ: /* 0x32 */ 1783/* File: x86/OP_IF_EQ.S */ 1784/* File: x86/bincmp.S */ 1785 /* 1786 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1787 * fragment that specifies the *reverse* comparison to perform, e.g. 1788 * for "if-le" you would use "gt". 1789 * 1790 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1791 */ 1792 /* if-cmp vA, vB, +CCCC */ 1793 movzx rINSTbl,%ecx # ecx <- A+ 1794 andb $0xf,%cl # ecx <- A 1795 GET_VREG_R %eax %ecx # eax <- vA 1796 sarl $4,rINST # rINST<- B 1797 movl rSELF,%ecx 1798 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1799 movl $2,%eax # assume not taken 1800 jne 1f 1801 movswl 2(rPC),%eax # Get signed branch offset 18021: 1803 movl offThread_curHandlerTable(%ecx),rIBASE 1804 FETCH_INST_INDEXED %eax 1805 ADVANCE_PC_INDEXED %eax 1806#if defined(WITH_JIT) 1807 GET_JIT_PROF_TABLE %ecx %eax 1808 cmp $0, %eax 1809 jne common_updateProfile # set up %ebx & %edx & rPC 1810#endif 1811 GOTO_NEXT 1812 1813 1814/* ------------------------------ */ 1815.L_OP_IF_NE: /* 0x33 */ 1816/* File: x86/OP_IF_NE.S */ 1817/* File: x86/bincmp.S */ 1818 /* 1819 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1820 * fragment that specifies the *reverse* comparison to perform, e.g. 1821 * for "if-le" you would use "gt". 1822 * 1823 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1824 */ 1825 /* if-cmp vA, vB, +CCCC */ 1826 movzx rINSTbl,%ecx # ecx <- A+ 1827 andb $0xf,%cl # ecx <- A 1828 GET_VREG_R %eax %ecx # eax <- vA 1829 sarl $4,rINST # rINST<- B 1830 movl rSELF,%ecx 1831 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1832 movl $2,%eax # assume not taken 1833 je 1f 1834 movswl 2(rPC),%eax # Get signed branch offset 18351: 1836 movl offThread_curHandlerTable(%ecx),rIBASE 1837 FETCH_INST_INDEXED %eax 1838 ADVANCE_PC_INDEXED %eax 1839#if defined(WITH_JIT) 1840 GET_JIT_PROF_TABLE %ecx %eax 1841 cmp $0, %eax 1842 jne common_updateProfile # set up %ebx & %edx & rPC 1843#endif 1844 GOTO_NEXT 1845 1846 1847/* ------------------------------ */ 1848.L_OP_IF_LT: /* 0x34 */ 1849/* File: x86/OP_IF_LT.S */ 1850/* File: x86/bincmp.S */ 1851 /* 1852 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1853 * fragment that specifies the *reverse* comparison to perform, e.g. 1854 * for "if-le" you would use "gt". 1855 * 1856 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1857 */ 1858 /* if-cmp vA, vB, +CCCC */ 1859 movzx rINSTbl,%ecx # ecx <- A+ 1860 andb $0xf,%cl # ecx <- A 1861 GET_VREG_R %eax %ecx # eax <- vA 1862 sarl $4,rINST # rINST<- B 1863 movl rSELF,%ecx 1864 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1865 movl $2,%eax # assume not taken 1866 jge 1f 1867 movswl 2(rPC),%eax # Get signed branch offset 18681: 1869 movl offThread_curHandlerTable(%ecx),rIBASE 1870 FETCH_INST_INDEXED %eax 1871 ADVANCE_PC_INDEXED %eax 1872#if defined(WITH_JIT) 1873 GET_JIT_PROF_TABLE %ecx %eax 1874 cmp $0, %eax 1875 jne common_updateProfile # set up %ebx & %edx & rPC 1876#endif 1877 GOTO_NEXT 1878 1879 1880/* ------------------------------ */ 1881.L_OP_IF_GE: /* 0x35 */ 1882/* File: x86/OP_IF_GE.S */ 1883/* File: x86/bincmp.S */ 1884 /* 1885 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1886 * fragment that specifies the *reverse* comparison to perform, e.g. 1887 * for "if-le" you would use "gt". 1888 * 1889 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1890 */ 1891 /* if-cmp vA, vB, +CCCC */ 1892 movzx rINSTbl,%ecx # ecx <- A+ 1893 andb $0xf,%cl # ecx <- A 1894 GET_VREG_R %eax %ecx # eax <- vA 1895 sarl $4,rINST # rINST<- B 1896 movl rSELF,%ecx 1897 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1898 movl $2,%eax # assume not taken 1899 jl 1f 1900 movswl 2(rPC),%eax # Get signed branch offset 19011: 1902 movl offThread_curHandlerTable(%ecx),rIBASE 1903 FETCH_INST_INDEXED %eax 1904 ADVANCE_PC_INDEXED %eax 1905#if defined(WITH_JIT) 1906 GET_JIT_PROF_TABLE %ecx %eax 1907 cmp $0, %eax 1908 jne common_updateProfile # set up %ebx & %edx & rPC 1909#endif 1910 GOTO_NEXT 1911 1912 1913/* ------------------------------ */ 1914.L_OP_IF_GT: /* 0x36 */ 1915/* File: x86/OP_IF_GT.S */ 1916/* File: x86/bincmp.S */ 1917 /* 1918 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1919 * fragment that specifies the *reverse* comparison to perform, e.g. 1920 * for "if-le" you would use "gt". 1921 * 1922 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1923 */ 1924 /* if-cmp vA, vB, +CCCC */ 1925 movzx rINSTbl,%ecx # ecx <- A+ 1926 andb $0xf,%cl # ecx <- A 1927 GET_VREG_R %eax %ecx # eax <- vA 1928 sarl $4,rINST # rINST<- B 1929 movl rSELF,%ecx 1930 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1931 movl $2,%eax # assume not taken 1932 jle 1f 1933 movswl 2(rPC),%eax # Get signed branch offset 19341: 1935 movl offThread_curHandlerTable(%ecx),rIBASE 1936 FETCH_INST_INDEXED %eax 1937 ADVANCE_PC_INDEXED %eax 1938#if defined(WITH_JIT) 1939 GET_JIT_PROF_TABLE %ecx %eax 1940 cmp $0, %eax 1941 jne common_updateProfile # set up %ebx & %edx & rPC 1942#endif 1943 GOTO_NEXT 1944 1945 1946/* ------------------------------ */ 1947.L_OP_IF_LE: /* 0x37 */ 1948/* File: x86/OP_IF_LE.S */ 1949/* File: x86/bincmp.S */ 1950 /* 1951 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1952 * fragment that specifies the *reverse* comparison to perform, e.g. 1953 * for "if-le" you would use "gt". 1954 * 1955 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1956 */ 1957 /* if-cmp vA, vB, +CCCC */ 1958 movzx rINSTbl,%ecx # ecx <- A+ 1959 andb $0xf,%cl # ecx <- A 1960 GET_VREG_R %eax %ecx # eax <- vA 1961 sarl $4,rINST # rINST<- B 1962 movl rSELF,%ecx 1963 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1964 movl $2,%eax # assume not taken 1965 jg 1f 1966 movswl 2(rPC),%eax # Get signed branch offset 19671: 1968 movl offThread_curHandlerTable(%ecx),rIBASE 1969 FETCH_INST_INDEXED %eax 1970 ADVANCE_PC_INDEXED %eax 1971#if defined(WITH_JIT) 1972 GET_JIT_PROF_TABLE %ecx %eax 1973 cmp $0, %eax 1974 jne common_updateProfile # set up %ebx & %edx & rPC 1975#endif 1976 GOTO_NEXT 1977 1978 1979/* ------------------------------ */ 1980.L_OP_IF_EQZ: /* 0x38 */ 1981/* File: x86/OP_IF_EQZ.S */ 1982/* File: x86/zcmp.S */ 1983 /* 1984 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1985 * fragment that specifies the *reverse* comparison to perform, e.g. 1986 * for "if-le" you would use "gt". 1987 * 1988 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1989 */ 1990 /* if-cmp vAA, +BBBB */ 1991 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 1992 movl rSELF,%ecx 1993 movl $2,%eax # assume branch not taken 1994 jne 1f 1995 movswl 2(rPC),%eax # fetch signed displacement 1996 movl offThread_curHandlerTable(%ecx),rIBASE 19971: 1998 FETCH_INST_INDEXED %eax 1999 ADVANCE_PC_INDEXED %eax 2000#if defined(WITH_JIT) 2001 GET_JIT_PROF_TABLE %ecx %eax 2002 cmp $0, %eax 2003 jne common_updateProfile # set up %ebx & %edx & rPC 2004#endif 2005 GOTO_NEXT 2006 2007 2008/* ------------------------------ */ 2009.L_OP_IF_NEZ: /* 0x39 */ 2010/* File: x86/OP_IF_NEZ.S */ 2011/* File: x86/zcmp.S */ 2012 /* 2013 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 2014 * fragment that specifies the *reverse* comparison to perform, e.g. 2015 * for "if-le" you would use "gt". 2016 * 2017 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 2018 */ 2019 /* if-cmp vAA, +BBBB */ 2020 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 2021 movl rSELF,%ecx 2022 movl $2,%eax # assume branch not taken 2023 je 1f 2024 movswl 2(rPC),%eax # fetch signed displacement 2025 movl offThread_curHandlerTable(%ecx),rIBASE 20261: 2027 FETCH_INST_INDEXED %eax 2028 ADVANCE_PC_INDEXED %eax 2029#if defined(WITH_JIT) 2030 GET_JIT_PROF_TABLE %ecx %eax 2031 cmp $0, %eax 2032 jne common_updateProfile # set up %ebx & %edx & rPC 2033#endif 2034 GOTO_NEXT 2035 2036 2037/* ------------------------------ */ 2038.L_OP_IF_LTZ: /* 0x3a */ 2039/* File: x86/OP_IF_LTZ.S */ 2040/* File: x86/zcmp.S */ 2041 /* 2042 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 2043 * fragment that specifies the *reverse* comparison to perform, e.g. 2044 * for "if-le" you would use "gt". 2045 * 2046 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 2047 */ 2048 /* if-cmp vAA, +BBBB */ 2049 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 2050 movl rSELF,%ecx 2051 movl $2,%eax # assume branch not taken 2052 jge 1f 2053 movswl 2(rPC),%eax # fetch signed displacement 2054 movl offThread_curHandlerTable(%ecx),rIBASE 20551: 2056 FETCH_INST_INDEXED %eax 2057 ADVANCE_PC_INDEXED %eax 2058#if defined(WITH_JIT) 2059 GET_JIT_PROF_TABLE %ecx %eax 2060 cmp $0, %eax 2061 jne common_updateProfile # set up %ebx & %edx & rPC 2062#endif 2063 GOTO_NEXT 2064 2065 2066/* ------------------------------ */ 2067.L_OP_IF_GEZ: /* 0x3b */ 2068/* File: x86/OP_IF_GEZ.S */ 2069/* File: x86/zcmp.S */ 2070 /* 2071 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 2072 * fragment that specifies the *reverse* comparison to perform, e.g. 2073 * for "if-le" you would use "gt". 2074 * 2075 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 2076 */ 2077 /* if-cmp vAA, +BBBB */ 2078 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 2079 movl rSELF,%ecx 2080 movl $2,%eax # assume branch not taken 2081 jl 1f 2082 movswl 2(rPC),%eax # fetch signed displacement 2083 movl offThread_curHandlerTable(%ecx),rIBASE 20841: 2085 FETCH_INST_INDEXED %eax 2086 ADVANCE_PC_INDEXED %eax 2087#if defined(WITH_JIT) 2088 GET_JIT_PROF_TABLE %ecx %eax 2089 cmp $0, %eax 2090 jne common_updateProfile # set up %ebx & %edx & rPC 2091#endif 2092 GOTO_NEXT 2093 2094 2095/* ------------------------------ */ 2096.L_OP_IF_GTZ: /* 0x3c */ 2097/* File: x86/OP_IF_GTZ.S */ 2098/* File: x86/zcmp.S */ 2099 /* 2100 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 2101 * fragment that specifies the *reverse* comparison to perform, e.g. 2102 * for "if-le" you would use "gt". 2103 * 2104 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 2105 */ 2106 /* if-cmp vAA, +BBBB */ 2107 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 2108 movl rSELF,%ecx 2109 movl $2,%eax # assume branch not taken 2110 jle 1f 2111 movswl 2(rPC),%eax # fetch signed displacement 2112 movl offThread_curHandlerTable(%ecx),rIBASE 21131: 2114 FETCH_INST_INDEXED %eax 2115 ADVANCE_PC_INDEXED %eax 2116#if defined(WITH_JIT) 2117 GET_JIT_PROF_TABLE %ecx %eax 2118 cmp $0, %eax 2119 jne common_updateProfile # set up %ebx & %edx & rPC 2120#endif 2121 GOTO_NEXT 2122 2123 2124/* ------------------------------ */ 2125.L_OP_IF_LEZ: /* 0x3d */ 2126/* File: x86/OP_IF_LEZ.S */ 2127/* File: x86/zcmp.S */ 2128 /* 2129 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 2130 * fragment that specifies the *reverse* comparison to perform, e.g. 2131 * for "if-le" you would use "gt". 2132 * 2133 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 2134 */ 2135 /* if-cmp vAA, +BBBB */ 2136 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 2137 movl rSELF,%ecx 2138 movl $2,%eax # assume branch not taken 2139 jg 1f 2140 movswl 2(rPC),%eax # fetch signed displacement 2141 movl offThread_curHandlerTable(%ecx),rIBASE 21421: 2143 FETCH_INST_INDEXED %eax 2144 ADVANCE_PC_INDEXED %eax 2145#if defined(WITH_JIT) 2146 GET_JIT_PROF_TABLE %ecx %eax 2147 cmp $0, %eax 2148 jne common_updateProfile # set up %ebx & %edx & rPC 2149#endif 2150 GOTO_NEXT 2151 2152 2153/* ------------------------------ */ 2154.L_OP_UNUSED_3E: /* 0x3e */ 2155/* File: x86/OP_UNUSED_3E.S */ 2156/* File: x86/unused.S */ 2157 jmp common_abort 2158 2159 2160/* ------------------------------ */ 2161.L_OP_UNUSED_3F: /* 0x3f */ 2162/* File: x86/OP_UNUSED_3F.S */ 2163/* File: x86/unused.S */ 2164 jmp common_abort 2165 2166 2167/* ------------------------------ */ 2168.L_OP_UNUSED_40: /* 0x40 */ 2169/* File: x86/OP_UNUSED_40.S */ 2170/* File: x86/unused.S */ 2171 jmp common_abort 2172 2173 2174/* ------------------------------ */ 2175.L_OP_UNUSED_41: /* 0x41 */ 2176/* File: x86/OP_UNUSED_41.S */ 2177/* File: x86/unused.S */ 2178 jmp common_abort 2179 2180 2181/* ------------------------------ */ 2182.L_OP_UNUSED_42: /* 0x42 */ 2183/* File: x86/OP_UNUSED_42.S */ 2184/* File: x86/unused.S */ 2185 jmp common_abort 2186 2187 2188/* ------------------------------ */ 2189.L_OP_UNUSED_43: /* 0x43 */ 2190/* File: x86/OP_UNUSED_43.S */ 2191/* File: x86/unused.S */ 2192 jmp common_abort 2193 2194 2195/* ------------------------------ */ 2196.L_OP_AGET: /* 0x44 */ 2197/* File: x86/OP_AGET.S */ 2198 /* 2199 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2200 * 2201 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2202 */ 2203 /* op vAA, vBB, vCC */ 2204 movzbl 2(rPC),%eax # eax<- BB 2205 movzbl 3(rPC),%ecx # ecx<- CC 2206 GET_VREG_R %eax %eax # eax<- vBB (array object) 2207 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2208 testl %eax,%eax # null array object? 2209 je common_errNullObject # bail if so 2210 cmpl offArrayObject_length(%eax),%ecx 2211 jae common_errArrayIndex # index >= length, bail. Expects 2212 # arrayObj in eax 2213 # index in ecx 2214 movl offArrayObject_contents(%eax,%ecx,4),%eax 2215.LOP_AGET_finish: 2216 FETCH_INST_OPCODE 2 %ecx 2217 SET_VREG %eax rINST 2218 ADVANCE_PC 2 2219 GOTO_NEXT_R %ecx 2220 2221/* ------------------------------ */ 2222.L_OP_AGET_WIDE: /* 0x45 */ 2223/* File: x86/OP_AGET_WIDE.S */ 2224 /* 2225 * Array get, 64 bits. vAA <- vBB[vCC]. 2226 * 2227 */ 2228 /* op vAA, vBB, vCC */ 2229 movzbl 2(rPC),%eax # eax<- BB 2230 movzbl 3(rPC),%ecx # ecx<- CC 2231 GET_VREG_R %eax %eax # eax<- vBB (array object) 2232 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2233 testl %eax,%eax # null array object? 2234 je common_errNullObject # bail if so 2235 cmpl offArrayObject_length(%eax),%ecx 2236 jae common_errArrayIndex # index >= length, bail. Expects 2237 # arrayObj in eax 2238 # index in ecx 2239 leal offArrayObject_contents(%eax,%ecx,8),%eax 2240 movl (%eax),%ecx 2241 movl 4(%eax),%eax 2242 SET_VREG_WORD %ecx rINST 0 2243 SET_VREG_WORD %eax rINST 1 2244 FETCH_INST_OPCODE 2 %ecx 2245 ADVANCE_PC 2 2246 GOTO_NEXT_R %ecx 2247 2248/* ------------------------------ */ 2249.L_OP_AGET_OBJECT: /* 0x46 */ 2250/* File: x86/OP_AGET_OBJECT.S */ 2251/* File: x86/OP_AGET.S */ 2252 /* 2253 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2254 * 2255 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2256 */ 2257 /* op vAA, vBB, vCC */ 2258 movzbl 2(rPC),%eax # eax<- BB 2259 movzbl 3(rPC),%ecx # ecx<- CC 2260 GET_VREG_R %eax %eax # eax<- vBB (array object) 2261 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2262 testl %eax,%eax # null array object? 2263 je common_errNullObject # bail if so 2264 cmpl offArrayObject_length(%eax),%ecx 2265 jae common_errArrayIndex # index >= length, bail. Expects 2266 # arrayObj in eax 2267 # index in ecx 2268 movl offArrayObject_contents(%eax,%ecx,4),%eax 2269.LOP_AGET_OBJECT_finish: 2270 FETCH_INST_OPCODE 2 %ecx 2271 SET_VREG %eax rINST 2272 ADVANCE_PC 2 2273 GOTO_NEXT_R %ecx 2274 2275 2276/* ------------------------------ */ 2277.L_OP_AGET_BOOLEAN: /* 0x47 */ 2278/* File: x86/OP_AGET_BOOLEAN.S */ 2279/* File: x86/OP_AGET.S */ 2280 /* 2281 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2282 * 2283 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2284 */ 2285 /* op vAA, vBB, vCC */ 2286 movzbl 2(rPC),%eax # eax<- BB 2287 movzbl 3(rPC),%ecx # ecx<- CC 2288 GET_VREG_R %eax %eax # eax<- vBB (array object) 2289 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2290 testl %eax,%eax # null array object? 2291 je common_errNullObject # bail if so 2292 cmpl offArrayObject_length(%eax),%ecx 2293 jae common_errArrayIndex # index >= length, bail. Expects 2294 # arrayObj in eax 2295 # index in ecx 2296 movzbl offArrayObject_contents(%eax,%ecx,1),%eax 2297.LOP_AGET_BOOLEAN_finish: 2298 FETCH_INST_OPCODE 2 %ecx 2299 SET_VREG %eax rINST 2300 ADVANCE_PC 2 2301 GOTO_NEXT_R %ecx 2302 2303 2304/* ------------------------------ */ 2305.L_OP_AGET_BYTE: /* 0x48 */ 2306/* File: x86/OP_AGET_BYTE.S */ 2307/* File: x86/OP_AGET.S */ 2308 /* 2309 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2310 * 2311 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2312 */ 2313 /* op vAA, vBB, vCC */ 2314 movzbl 2(rPC),%eax # eax<- BB 2315 movzbl 3(rPC),%ecx # ecx<- CC 2316 GET_VREG_R %eax %eax # eax<- vBB (array object) 2317 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2318 testl %eax,%eax # null array object? 2319 je common_errNullObject # bail if so 2320 cmpl offArrayObject_length(%eax),%ecx 2321 jae common_errArrayIndex # index >= length, bail. Expects 2322 # arrayObj in eax 2323 # index in ecx 2324 movsbl offArrayObject_contents(%eax,%ecx,1),%eax 2325.LOP_AGET_BYTE_finish: 2326 FETCH_INST_OPCODE 2 %ecx 2327 SET_VREG %eax rINST 2328 ADVANCE_PC 2 2329 GOTO_NEXT_R %ecx 2330 2331 2332/* ------------------------------ */ 2333.L_OP_AGET_CHAR: /* 0x49 */ 2334/* File: x86/OP_AGET_CHAR.S */ 2335/* File: x86/OP_AGET.S */ 2336 /* 2337 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2338 * 2339 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2340 */ 2341 /* op vAA, vBB, vCC */ 2342 movzbl 2(rPC),%eax # eax<- BB 2343 movzbl 3(rPC),%ecx # ecx<- CC 2344 GET_VREG_R %eax %eax # eax<- vBB (array object) 2345 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2346 testl %eax,%eax # null array object? 2347 je common_errNullObject # bail if so 2348 cmpl offArrayObject_length(%eax),%ecx 2349 jae common_errArrayIndex # index >= length, bail. Expects 2350 # arrayObj in eax 2351 # index in ecx 2352 movzwl offArrayObject_contents(%eax,%ecx,2),%eax 2353.LOP_AGET_CHAR_finish: 2354 FETCH_INST_OPCODE 2 %ecx 2355 SET_VREG %eax rINST 2356 ADVANCE_PC 2 2357 GOTO_NEXT_R %ecx 2358 2359 2360/* ------------------------------ */ 2361.L_OP_AGET_SHORT: /* 0x4a */ 2362/* File: x86/OP_AGET_SHORT.S */ 2363/* File: x86/OP_AGET.S */ 2364 /* 2365 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2366 * 2367 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2368 */ 2369 /* op vAA, vBB, vCC */ 2370 movzbl 2(rPC),%eax # eax<- BB 2371 movzbl 3(rPC),%ecx # ecx<- CC 2372 GET_VREG_R %eax %eax # eax<- vBB (array object) 2373 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2374 testl %eax,%eax # null array object? 2375 je common_errNullObject # bail if so 2376 cmpl offArrayObject_length(%eax),%ecx 2377 jae common_errArrayIndex # index >= length, bail. Expects 2378 # arrayObj in eax 2379 # index in ecx 2380 movswl offArrayObject_contents(%eax,%ecx,2),%eax 2381.LOP_AGET_SHORT_finish: 2382 FETCH_INST_OPCODE 2 %ecx 2383 SET_VREG %eax rINST 2384 ADVANCE_PC 2 2385 GOTO_NEXT_R %ecx 2386 2387 2388/* ------------------------------ */ 2389.L_OP_APUT: /* 0x4b */ 2390/* File: x86/OP_APUT.S */ 2391 /* 2392 * Array put, 32 bits or less. vBB[vCC] <- vAA 2393 * 2394 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2395 */ 2396 /* op vAA, vBB, vCC */ 2397 movzbl 2(rPC),%eax # eax<- BB 2398 movzbl 3(rPC),%ecx # ecx<- CC 2399 GET_VREG_R %eax %eax # eax<- vBB (array object) 2400 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2401 testl %eax,%eax # null array object? 2402 je common_errNullObject # bail if so 2403 cmpl offArrayObject_length(%eax),%ecx 2404 jae common_errArrayIndex # index >= length, bail. Expects: 2405 # arrayObj in eax 2406 # index in ecx 2407 leal offArrayObject_contents(%eax,%ecx,4),%eax 2408.LOP_APUT_finish: 2409 GET_VREG_R rINST rINST 2410 FETCH_INST_OPCODE 2 %ecx 2411 movl rINST,(%eax) 2412 ADVANCE_PC 2 2413 GOTO_NEXT_R %ecx 2414 2415/* ------------------------------ */ 2416.L_OP_APUT_WIDE: /* 0x4c */ 2417/* File: x86/OP_APUT_WIDE.S */ 2418 /* 2419 * Array put, 64 bits. vBB[vCC]<-vAA. 2420 * 2421 */ 2422 /* op vAA, vBB, vCC */ 2423 movzbl 2(rPC),%eax # eax<- BB 2424 movzbl 3(rPC),%ecx # ecx<- CC 2425 GET_VREG_R %eax %eax # eax<- vBB (array object) 2426 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2427 testl %eax,%eax # null array object? 2428 je common_errNullObject # bail if so 2429 cmpl offArrayObject_length(%eax),%ecx 2430 jae common_errArrayIndex # index >= length, bail. Expects: 2431 # arrayObj in eax 2432 # index in ecx 2433 leal offArrayObject_contents(%eax,%ecx,8),%eax 2434 GET_VREG_WORD %ecx rINST 0 2435 GET_VREG_WORD rINST rINST 1 2436 movl %ecx,(%eax) 2437 FETCH_INST_OPCODE 2 %ecx 2438 movl rINST,4(%eax) 2439 ADVANCE_PC 2 2440 GOTO_NEXT_R %ecx 2441 2442/* ------------------------------ */ 2443.L_OP_APUT_OBJECT: /* 0x4d */ 2444/* File: x86/OP_APUT_OBJECT.S */ 2445 /* 2446 * Array put, 32 bits or less. vBB[vCC] <- vAA 2447 * 2448 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2449 */ 2450 /* op vAA, vBB, vCC */ 2451 movzbl 2(rPC),%eax # eax<- BB 2452 movzbl 3(rPC),%ecx # ecx<- CC 2453 GET_VREG_R %eax %eax # eax<- vBB (array object) 2454 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2455 GET_VREG_R rINST rINST # rINST<- vAA 2456 testl %eax,%eax # null array object? 2457 je common_errNullObject # bail if so 2458 cmpl offArrayObject_length(%eax),%ecx 2459 jae common_errArrayIndex # index >= length, bail. Expects 2460 # arrayObj in eax 2461 # index in ecx 2462 /* On entry: 2463 * eax<- array object 2464 * ecx<- index 2465 * rINST<- vAA 2466 */ 2467 leal offArrayObject_contents(%eax,%ecx,4),%ecx 2468 testl rINST,rINST # storing null reference? 2469 je .LOP_APUT_OBJECT_skip_check 2470 SPILL_TMP1(%ecx) # save target address 2471 SPILL_TMP2(%eax) # save object head 2472 movl offObject_clazz(%eax),%eax # eax<- arrayObj->clazz 2473 movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz 2474 movl %eax,OUT_ARG1(%esp) 2475 movl %ecx,OUT_ARG0(%esp) 2476 movl %ecx,sReg0 # store the two classes for later 2477 movl %eax,sReg1 2478 SPILL(rIBASE) 2479 call dvmCanPutArrayElement # test object type vs. array type 2480 UNSPILL(rIBASE) 2481 UNSPILL_TMP1(%ecx) # recover target address 2482 testl %eax,%eax 2483 movl rSELF,%eax 2484 jne .LOP_APUT_OBJECT_types_okay 2485 2486 # The types don't match. We need to throw an ArrayStoreException. 2487 EXPORT_PC 2488 movl sReg0,%eax # restore the two classes... 2489 movl %eax,OUT_ARG0(%esp) 2490 movl sReg1,%ecx 2491 movl %ecx,OUT_ARG1(%esp) 2492 call dvmThrowArrayStoreExceptionIncompatibleElement # ...and throw 2493 jmp common_exceptionThrown 2494 2495.LOP_APUT_OBJECT_types_okay: 2496 movl offThread_cardTable(%eax),%eax # get card table base 2497 movl rINST,(%ecx) # store into array 2498 UNSPILL_TMP2(rINST) # recover object head 2499 FETCH_INST_OPCODE 2 %ecx 2500 shrl $GC_CARD_SHIFT,rINST # object head to card number 2501 movb %al,(%eax,rINST) # mark card using object head 2502 ADVANCE_PC 2 2503 GOTO_NEXT_R %ecx 2504 2505.LOP_APUT_OBJECT_skip_check: 2506 movl rINST,(%ecx) 2507 FETCH_INST_OPCODE 2 %ecx 2508 ADVANCE_PC 2 2509 GOTO_NEXT_R %ecx 2510 2511/* ------------------------------ */ 2512.L_OP_APUT_BOOLEAN: /* 0x4e */ 2513/* File: x86/OP_APUT_BOOLEAN.S */ 2514/* File: x86/OP_APUT.S */ 2515 /* 2516 * Array put, 32 bits or less. vBB[vCC] <- vAA 2517 * 2518 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2519 */ 2520 /* op vAA, vBB, vCC */ 2521 movzbl 2(rPC),%eax # eax<- BB 2522 movzbl 3(rPC),%ecx # ecx<- CC 2523 GET_VREG_R %eax %eax # eax<- vBB (array object) 2524 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2525 testl %eax,%eax # null array object? 2526 je common_errNullObject # bail if so 2527 cmpl offArrayObject_length(%eax),%ecx 2528 jae common_errArrayIndex # index >= length, bail. Expects: 2529 # arrayObj in eax 2530 # index in ecx 2531 leal offArrayObject_contents(%eax,%ecx,1),%eax 2532.LOP_APUT_BOOLEAN_finish: 2533 GET_VREG_R rINST rINST 2534 FETCH_INST_OPCODE 2 %ecx 2535 movb rINSTbl,(%eax) 2536 ADVANCE_PC 2 2537 GOTO_NEXT_R %ecx 2538 2539 2540/* ------------------------------ */ 2541.L_OP_APUT_BYTE: /* 0x4f */ 2542/* File: x86/OP_APUT_BYTE.S */ 2543/* File: x86/OP_APUT.S */ 2544 /* 2545 * Array put, 32 bits or less. vBB[vCC] <- vAA 2546 * 2547 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2548 */ 2549 /* op vAA, vBB, vCC */ 2550 movzbl 2(rPC),%eax # eax<- BB 2551 movzbl 3(rPC),%ecx # ecx<- CC 2552 GET_VREG_R %eax %eax # eax<- vBB (array object) 2553 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2554 testl %eax,%eax # null array object? 2555 je common_errNullObject # bail if so 2556 cmpl offArrayObject_length(%eax),%ecx 2557 jae common_errArrayIndex # index >= length, bail. Expects: 2558 # arrayObj in eax 2559 # index in ecx 2560 leal offArrayObject_contents(%eax,%ecx,1),%eax 2561.LOP_APUT_BYTE_finish: 2562 GET_VREG_R rINST rINST 2563 FETCH_INST_OPCODE 2 %ecx 2564 movb rINSTbl,(%eax) 2565 ADVANCE_PC 2 2566 GOTO_NEXT_R %ecx 2567 2568 2569/* ------------------------------ */ 2570.L_OP_APUT_CHAR: /* 0x50 */ 2571/* File: x86/OP_APUT_CHAR.S */ 2572/* File: x86/OP_APUT.S */ 2573 /* 2574 * Array put, 32 bits or less. vBB[vCC] <- vAA 2575 * 2576 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2577 */ 2578 /* op vAA, vBB, vCC */ 2579 movzbl 2(rPC),%eax # eax<- BB 2580 movzbl 3(rPC),%ecx # ecx<- CC 2581 GET_VREG_R %eax %eax # eax<- vBB (array object) 2582 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2583 testl %eax,%eax # null array object? 2584 je common_errNullObject # bail if so 2585 cmpl offArrayObject_length(%eax),%ecx 2586 jae common_errArrayIndex # index >= length, bail. Expects: 2587 # arrayObj in eax 2588 # index in ecx 2589 leal offArrayObject_contents(%eax,%ecx,2),%eax 2590.LOP_APUT_CHAR_finish: 2591 GET_VREG_R rINST rINST 2592 FETCH_INST_OPCODE 2 %ecx 2593 movw rINSTw,(%eax) 2594 ADVANCE_PC 2 2595 GOTO_NEXT_R %ecx 2596 2597 2598/* ------------------------------ */ 2599.L_OP_APUT_SHORT: /* 0x51 */ 2600/* File: x86/OP_APUT_SHORT.S */ 2601/* File: x86/OP_APUT.S */ 2602 /* 2603 * Array put, 32 bits or less. vBB[vCC] <- vAA 2604 * 2605 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2606 */ 2607 /* op vAA, vBB, vCC */ 2608 movzbl 2(rPC),%eax # eax<- BB 2609 movzbl 3(rPC),%ecx # ecx<- CC 2610 GET_VREG_R %eax %eax # eax<- vBB (array object) 2611 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2612 testl %eax,%eax # null array object? 2613 je common_errNullObject # bail if so 2614 cmpl offArrayObject_length(%eax),%ecx 2615 jae common_errArrayIndex # index >= length, bail. Expects: 2616 # arrayObj in eax 2617 # index in ecx 2618 leal offArrayObject_contents(%eax,%ecx,2),%eax 2619.LOP_APUT_SHORT_finish: 2620 GET_VREG_R rINST rINST 2621 FETCH_INST_OPCODE 2 %ecx 2622 movw rINSTw,(%eax) 2623 ADVANCE_PC 2 2624 GOTO_NEXT_R %ecx 2625 2626 2627/* ------------------------------ */ 2628.L_OP_IGET: /* 0x52 */ 2629/* File: x86/OP_IGET.S */ 2630 /* 2631 * General 32-bit instance field get. 2632 * 2633 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2634 */ 2635 /* op vA, vB, field@CCCC */ 2636 movl rSELF,%ecx 2637 SPILL(rIBASE) # preserve rIBASE 2638 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 2639 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2640 movzbl rINSTbl,%ecx # ecx<- BA 2641 sarl $4,%ecx # ecx<- B 2642 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2643 andb $0xf,rINSTbl # rINST<- A 2644 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2645 movl (%eax,rIBASE,4),%eax # resolved entry 2646 testl %eax,%eax # is resolved entry null? 2647 jne .LOP_IGET_finish # no, already resolved 2648 movl rIBASE,OUT_ARG1(%esp) # needed by dvmResolveInstField 2649 movl rSELF,rIBASE 2650 EXPORT_PC 2651 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 2652 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 2653 SPILL_TMP1(%ecx) # save obj pointer across call 2654 movl rIBASE,OUT_ARG0(%esp) # pass in method->clazz 2655 call dvmResolveInstField # ... to dvmResolveInstField 2656 UNSPILL_TMP1(%ecx) 2657 testl %eax,%eax # returns InstrField ptr 2658 jne .LOP_IGET_finish 2659 jmp common_exceptionThrown 2660 2661.LOP_IGET_finish: 2662 /* 2663 * Currently: 2664 * eax holds resolved field 2665 * ecx holds object 2666 * rINST holds A 2667 */ 2668 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 2669 testl %ecx,%ecx # object null? 2670 je common_errNullObject # object was null 2671 movl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 2672 FETCH_INST_OPCODE 2 %eax 2673 UNSPILL(rIBASE) 2674 SET_VREG %ecx rINST 2675 ADVANCE_PC 2 2676 GOTO_NEXT_R %eax 2677 2678/* ------------------------------ */ 2679.L_OP_IGET_WIDE: /* 0x53 */ 2680/* File: x86/OP_IGET_WIDE.S */ 2681 /* 2682 * 64-bit instance field get. 2683 * 2684 */ 2685 /* op vA, vB, field@CCCC */ 2686 movl rSELF,%ecx 2687 SPILL(rIBASE) # preserve rIBASE 2688 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 2689 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2690 movzbl rINSTbl,%ecx # ecx<- BA 2691 sarl $4,%ecx # ecx<- B 2692 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2693 andb $0xf,rINSTbl # rINST<- A 2694 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2695 movl (%eax,rIBASE,4),%eax # resolved entry 2696 testl %eax,%eax # is resolved entry null? 2697 jne .LOP_IGET_WIDE_finish # no, already resolved 2698 movl rIBASE,OUT_ARG1(%esp) # for dvmResolveInstField 2699 movl rSELF,rIBASE 2700 EXPORT_PC 2701 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 2702 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 2703 SPILL_TMP1(%ecx) # save objpointer across call 2704 movl rPC,OUT_ARG0(%esp) # pass in method->clazz 2705 call dvmResolveInstField # ... to dvmResolveInstField 2706 UNSPILL_TMP1(%ecx) 2707 testl %eax,%eax # returns InstrField ptr 2708 jne .LOP_IGET_WIDE_finish 2709 jmp common_exceptionThrown 2710 2711.LOP_IGET_WIDE_finish: 2712 /* 2713 * Currently: 2714 * eax holds resolved field 2715 * ecx holds object 2716 * rINST holds A 2717 */ 2718 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 2719 testl %ecx,%ecx # object null? 2720 je common_errNullObject # object was null 2721 leal (%ecx,%eax,1),%eax # eax<- address of field 2722 movl (%eax),%ecx # ecx<- lsw 2723 movl 4(%eax),%eax # eax<- msw 2724 SET_VREG_WORD %ecx rINST 0 2725 FETCH_INST_OPCODE 2 %ecx 2726 UNSPILL(rIBASE) # restore rIBASE 2727 SET_VREG_WORD %eax rINST 1 2728 ADVANCE_PC 2 2729 GOTO_NEXT_R %ecx 2730 2731/* ------------------------------ */ 2732.L_OP_IGET_OBJECT: /* 0x54 */ 2733/* File: x86/OP_IGET_OBJECT.S */ 2734/* File: x86/OP_IGET.S */ 2735 /* 2736 * General 32-bit instance field get. 2737 * 2738 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2739 */ 2740 /* op vA, vB, field@CCCC */ 2741 movl rSELF,%ecx 2742 SPILL(rIBASE) # preserve rIBASE 2743 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 2744 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2745 movzbl rINSTbl,%ecx # ecx<- BA 2746 sarl $4,%ecx # ecx<- B 2747 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2748 andb $0xf,rINSTbl # rINST<- A 2749 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2750 movl (%eax,rIBASE,4),%eax # resolved entry 2751 testl %eax,%eax # is resolved entry null? 2752 jne .LOP_IGET_OBJECT_finish # no, already resolved 2753 movl rIBASE,OUT_ARG1(%esp) # needed by dvmResolveInstField 2754 movl rSELF,rIBASE 2755 EXPORT_PC 2756 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 2757 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 2758 SPILL_TMP1(%ecx) # save obj pointer across call 2759 movl rIBASE,OUT_ARG0(%esp) # pass in method->clazz 2760 call dvmResolveInstField # ... to dvmResolveInstField 2761 UNSPILL_TMP1(%ecx) 2762 testl %eax,%eax # returns InstrField ptr 2763 jne .LOP_IGET_OBJECT_finish 2764 jmp common_exceptionThrown 2765 2766.LOP_IGET_OBJECT_finish: 2767 /* 2768 * Currently: 2769 * eax holds resolved field 2770 * ecx holds object 2771 * rINST holds A 2772 */ 2773 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 2774 testl %ecx,%ecx # object null? 2775 je common_errNullObject # object was null 2776 movl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 2777 FETCH_INST_OPCODE 2 %eax 2778 UNSPILL(rIBASE) 2779 SET_VREG %ecx rINST 2780 ADVANCE_PC 2 2781 GOTO_NEXT_R %eax 2782 2783 2784/* ------------------------------ */ 2785.L_OP_IGET_BOOLEAN: /* 0x55 */ 2786/* File: x86/OP_IGET_BOOLEAN.S */ 2787/* File: x86/OP_IGET.S */ 2788 /* 2789 * General 32-bit instance field get. 2790 * 2791 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2792 */ 2793 /* op vA, vB, field@CCCC */ 2794 movl rSELF,%ecx 2795 SPILL(rIBASE) # preserve rIBASE 2796 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 2797 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2798 movzbl rINSTbl,%ecx # ecx<- BA 2799 sarl $4,%ecx # ecx<- B 2800 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2801 andb $0xf,rINSTbl # rINST<- A 2802 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2803 movl (%eax,rIBASE,4),%eax # resolved entry 2804 testl %eax,%eax # is resolved entry null? 2805 jne .LOP_IGET_BOOLEAN_finish # no, already resolved 2806 movl rIBASE,OUT_ARG1(%esp) # needed by dvmResolveInstField 2807 movl rSELF,rIBASE 2808 EXPORT_PC 2809 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 2810 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 2811 SPILL_TMP1(%ecx) # save obj pointer across call 2812 movl rIBASE,OUT_ARG0(%esp) # pass in method->clazz 2813 call dvmResolveInstField # ... to dvmResolveInstField 2814 UNSPILL_TMP1(%ecx) 2815 testl %eax,%eax # returns InstrField ptr 2816 jne .LOP_IGET_BOOLEAN_finish 2817 jmp common_exceptionThrown 2818 2819.LOP_IGET_BOOLEAN_finish: 2820 /* 2821 * Currently: 2822 * eax holds resolved field 2823 * ecx holds object 2824 * rINST holds A 2825 */ 2826 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 2827 testl %ecx,%ecx # object null? 2828 je common_errNullObject # object was null 2829 movzbl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 2830 FETCH_INST_OPCODE 2 %eax 2831 UNSPILL(rIBASE) 2832 SET_VREG %ecx rINST 2833 ADVANCE_PC 2 2834 GOTO_NEXT_R %eax 2835 2836 2837/* ------------------------------ */ 2838.L_OP_IGET_BYTE: /* 0x56 */ 2839/* File: x86/OP_IGET_BYTE.S */ 2840/* File: x86/OP_IGET.S */ 2841 /* 2842 * General 32-bit instance field get. 2843 * 2844 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2845 */ 2846 /* op vA, vB, field@CCCC */ 2847 movl rSELF,%ecx 2848 SPILL(rIBASE) # preserve rIBASE 2849 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 2850 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2851 movzbl rINSTbl,%ecx # ecx<- BA 2852 sarl $4,%ecx # ecx<- B 2853 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2854 andb $0xf,rINSTbl # rINST<- A 2855 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2856 movl (%eax,rIBASE,4),%eax # resolved entry 2857 testl %eax,%eax # is resolved entry null? 2858 jne .LOP_IGET_BYTE_finish # no, already resolved 2859 movl rIBASE,OUT_ARG1(%esp) # needed by dvmResolveInstField 2860 movl rSELF,rIBASE 2861 EXPORT_PC 2862 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 2863 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 2864 SPILL_TMP1(%ecx) # save obj pointer across call 2865 movl rIBASE,OUT_ARG0(%esp) # pass in method->clazz 2866 call dvmResolveInstField # ... to dvmResolveInstField 2867 UNSPILL_TMP1(%ecx) 2868 testl %eax,%eax # returns InstrField ptr 2869 jne .LOP_IGET_BYTE_finish 2870 jmp common_exceptionThrown 2871 2872.LOP_IGET_BYTE_finish: 2873 /* 2874 * Currently: 2875 * eax holds resolved field 2876 * ecx holds object 2877 * rINST holds A 2878 */ 2879 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 2880 testl %ecx,%ecx # object null? 2881 je common_errNullObject # object was null 2882 movsbl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 2883 FETCH_INST_OPCODE 2 %eax 2884 UNSPILL(rIBASE) 2885 SET_VREG %ecx rINST 2886 ADVANCE_PC 2 2887 GOTO_NEXT_R %eax 2888 2889 2890/* ------------------------------ */ 2891.L_OP_IGET_CHAR: /* 0x57 */ 2892/* File: x86/OP_IGET_CHAR.S */ 2893/* File: x86/OP_IGET.S */ 2894 /* 2895 * General 32-bit instance field get. 2896 * 2897 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2898 */ 2899 /* op vA, vB, field@CCCC */ 2900 movl rSELF,%ecx 2901 SPILL(rIBASE) # preserve rIBASE 2902 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 2903 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2904 movzbl rINSTbl,%ecx # ecx<- BA 2905 sarl $4,%ecx # ecx<- B 2906 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2907 andb $0xf,rINSTbl # rINST<- A 2908 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2909 movl (%eax,rIBASE,4),%eax # resolved entry 2910 testl %eax,%eax # is resolved entry null? 2911 jne .LOP_IGET_CHAR_finish # no, already resolved 2912 movl rIBASE,OUT_ARG1(%esp) # needed by dvmResolveInstField 2913 movl rSELF,rIBASE 2914 EXPORT_PC 2915 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 2916 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 2917 SPILL_TMP1(%ecx) # save obj pointer across call 2918 movl rIBASE,OUT_ARG0(%esp) # pass in method->clazz 2919 call dvmResolveInstField # ... to dvmResolveInstField 2920 UNSPILL_TMP1(%ecx) 2921 testl %eax,%eax # returns InstrField ptr 2922 jne .LOP_IGET_CHAR_finish 2923 jmp common_exceptionThrown 2924 2925.LOP_IGET_CHAR_finish: 2926 /* 2927 * Currently: 2928 * eax holds resolved field 2929 * ecx holds object 2930 * rINST holds A 2931 */ 2932 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 2933 testl %ecx,%ecx # object null? 2934 je common_errNullObject # object was null 2935 movzwl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 2936 FETCH_INST_OPCODE 2 %eax 2937 UNSPILL(rIBASE) 2938 SET_VREG %ecx rINST 2939 ADVANCE_PC 2 2940 GOTO_NEXT_R %eax 2941 2942 2943/* ------------------------------ */ 2944.L_OP_IGET_SHORT: /* 0x58 */ 2945/* File: x86/OP_IGET_SHORT.S */ 2946/* File: x86/OP_IGET.S */ 2947 /* 2948 * General 32-bit instance field get. 2949 * 2950 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2951 */ 2952 /* op vA, vB, field@CCCC */ 2953 movl rSELF,%ecx 2954 SPILL(rIBASE) # preserve rIBASE 2955 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 2956 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2957 movzbl rINSTbl,%ecx # ecx<- BA 2958 sarl $4,%ecx # ecx<- B 2959 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2960 andb $0xf,rINSTbl # rINST<- A 2961 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2962 movl (%eax,rIBASE,4),%eax # resolved entry 2963 testl %eax,%eax # is resolved entry null? 2964 jne .LOP_IGET_SHORT_finish # no, already resolved 2965 movl rIBASE,OUT_ARG1(%esp) # needed by dvmResolveInstField 2966 movl rSELF,rIBASE 2967 EXPORT_PC 2968 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 2969 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 2970 SPILL_TMP1(%ecx) # save obj pointer across call 2971 movl rIBASE,OUT_ARG0(%esp) # pass in method->clazz 2972 call dvmResolveInstField # ... to dvmResolveInstField 2973 UNSPILL_TMP1(%ecx) 2974 testl %eax,%eax # returns InstrField ptr 2975 jne .LOP_IGET_SHORT_finish 2976 jmp common_exceptionThrown 2977 2978.LOP_IGET_SHORT_finish: 2979 /* 2980 * Currently: 2981 * eax holds resolved field 2982 * ecx holds object 2983 * rINST holds A 2984 */ 2985 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 2986 testl %ecx,%ecx # object null? 2987 je common_errNullObject # object was null 2988 movswl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 2989 FETCH_INST_OPCODE 2 %eax 2990 UNSPILL(rIBASE) 2991 SET_VREG %ecx rINST 2992 ADVANCE_PC 2 2993 GOTO_NEXT_R %eax 2994 2995 2996/* ------------------------------ */ 2997.L_OP_IPUT: /* 0x59 */ 2998/* File: x86/OP_IPUT.S */ 2999 3000 /* 3001 * General 32-bit instance field put. 3002 * 3003 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 3004 */ 3005 /* op vA, vB, field@CCCC */ 3006 movl rSELF,%ecx 3007 SPILL (rIBASE) 3008 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 3009 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 3010 movzbl rINSTbl,%ecx # ecx<- BA 3011 sarl $4,%ecx # ecx<- B 3012 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 3013 andb $0xf,rINSTbl # rINST<- A 3014 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 3015 movl (%eax,rIBASE,4),%eax # resolved entry 3016 testl %eax,%eax # is resolved entry null? 3017 jne .LOP_IPUT_finish # no, already resolved 3018 movl rIBASE,OUT_ARG1(%esp) 3019 movl rSELF,rIBASE 3020 EXPORT_PC 3021 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 3022 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 3023 SPILL_TMP1(%ecx) # save obj pointer across call 3024 movl rIBASE,OUT_ARG0(%esp) # pass in method->clazz 3025 call dvmResolveInstField # ... to dvmResolveInstField 3026 UNSPILL_TMP1(%ecx) 3027 testl %eax,%eax # returns InstrField ptr 3028 jne .LOP_IPUT_finish 3029 jmp common_exceptionThrown 3030 3031.LOP_IPUT_finish: 3032 /* 3033 * Currently: 3034 * eax holds resolved field 3035 * ecx holds object 3036 * rINST holds A 3037 */ 3038 GET_VREG_R rINST rINST # rINST<- v[A] 3039 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 3040 testl %ecx,%ecx # object null? 3041 je common_errNullObject # object was null 3042 movl rINST,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 3043 FETCH_INST_OPCODE 2 %ecx 3044 UNSPILL(rIBASE) 3045 ADVANCE_PC 2 3046 GOTO_NEXT_R %ecx 3047 3048/* ------------------------------ */ 3049.L_OP_IPUT_WIDE: /* 0x5a */ 3050/* File: x86/OP_IPUT_WIDE.S */ 3051 /* 3052 * 64-bit instance field put. 3053 * 3054 */ 3055 /* op vA, vB, field@CCCC */ 3056 movl rSELF,%ecx 3057 SPILL(rIBASE) 3058 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 3059 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 3060 movzbl rINSTbl,%ecx # ecx<- BA 3061 sarl $4,%ecx # ecx<- B 3062 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 3063 andb $0xf,rINSTbl # rINST<- A 3064 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 3065 movl (%eax,rIBASE,4),%eax # resolved entry 3066 testl %eax,%eax # is resolved entry null? 3067 jne .LOP_IPUT_WIDE_finish # no, already resolved 3068 movl rIBASE,OUT_ARG1(%esp) 3069 movl rSELF,rIBASE 3070 EXPORT_PC 3071 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 3072 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 3073 SPILL_TMP1(%ecx) # save obj pointer across call 3074 movl rIBASE,OUT_ARG0(%esp) # pass in method->clazz 3075 call dvmResolveInstField # ... to dvmResolveInstField 3076 UNSPILL_TMP1(%ecx) 3077 testl %eax,%eax # ... which returns InstrField ptr 3078 jne .LOP_IPUT_WIDE_finish 3079 jmp common_exceptionThrown 3080 3081.LOP_IPUT_WIDE_finish: 3082 /* 3083 * Currently: 3084 * eax holds resolved field 3085 * ecx holds object 3086 * rIBASE is scratch, but needs to be unspilled 3087 * rINST holds A 3088 */ 3089 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 3090 testl %ecx,%ecx # object null? 3091 je common_errNullObject # object was null 3092 leal (%ecx,%eax,1),%eax # eax<- address of field 3093 GET_VREG_WORD %ecx rINST 0 # ecx<- lsw 3094 GET_VREG_WORD rINST rINST 1 # rINST<- msw 3095 movl rINST,4(%eax) 3096 movl %ecx,(%eax) 3097 FETCH_INST_OPCODE 2 %ecx 3098 UNSPILL(rIBASE) 3099 ADVANCE_PC 2 3100 GOTO_NEXT_R %ecx 3101 3102/* ------------------------------ */ 3103.L_OP_IPUT_OBJECT: /* 0x5b */ 3104/* File: x86/OP_IPUT_OBJECT.S */ 3105 /* 3106 * Object field put. 3107 * 3108 * for: iput-object 3109 */ 3110 /* op vA, vB, field@CCCC */ 3111 movl rSELF,%ecx 3112 SPILL(rIBASE) 3113 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 3114 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 3115 movzbl rINSTbl,%ecx # ecx<- BA 3116 sarl $4,%ecx # ecx<- B 3117 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 3118 andb $0xf,rINSTbl # rINST<- A 3119 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 3120 movl (%eax,rIBASE,4),%eax # resolved entry 3121 testl %eax,%eax # is resolved entry null? 3122 jne .LOP_IPUT_OBJECT_finish # no, already resolved 3123 movl rIBASE,OUT_ARG1(%esp) 3124 movl rSELF,rIBASE 3125 EXPORT_PC 3126 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 3127 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 3128 SPILL_TMP1(%ecx) # save obj pointer across call 3129 movl rIBASE,OUT_ARG0(%esp) # pass in method->clazz 3130 call dvmResolveInstField # ... to dvmResolveInstField 3131 UNSPILL_TMP1(%ecx) 3132 testl %eax,%eax # returns InstrField ptr 3133 jne .LOP_IPUT_OBJECT_finish 3134 jmp common_exceptionThrown 3135 3136.LOP_IPUT_OBJECT_finish: 3137 /* 3138 * Currently: 3139 * eax holds resolved field 3140 * ecx holds object 3141 * rIBASE is scratch, but needs to be unspilled 3142 * rINST holds A 3143 */ 3144 GET_VREG_R rINST rINST # rINST<- v[A] 3145 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 3146 testl %ecx,%ecx # object null? 3147 je common_errNullObject # object was null 3148 movl rINST,(%ecx,%eax) # obj.field <- v[A](8/16/32 bits) 3149 movl rSELF,%eax 3150 testl rINST,rINST # stored a NULL? 3151 movl offThread_cardTable(%eax),%eax # get card table base 3152 je 1f # skip card mark if null store 3153 shrl $GC_CARD_SHIFT,%ecx # object head to card number 3154 movb %al,(%eax,%ecx) # mark card using object head 31551: 3156 UNSPILL(rIBASE) 3157 FETCH_INST_OPCODE 2 %ecx 3158 ADVANCE_PC 2 3159 GOTO_NEXT_R %ecx 3160 3161/* ------------------------------ */ 3162.L_OP_IPUT_BOOLEAN: /* 0x5c */ 3163/* File: x86/OP_IPUT_BOOLEAN.S */ 3164/* File: x86/OP_IPUT.S */ 3165 3166 /* 3167 * General 32-bit instance field put. 3168 * 3169 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 3170 */ 3171 /* op vA, vB, field@CCCC */ 3172 movl rSELF,%ecx 3173 SPILL (rIBASE) 3174 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 3175 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 3176 movzbl rINSTbl,%ecx # ecx<- BA 3177 sarl $4,%ecx # ecx<- B 3178 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 3179 andb $0xf,rINSTbl # rINST<- A 3180 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 3181 movl (%eax,rIBASE,4),%eax # resolved entry 3182 testl %eax,%eax # is resolved entry null? 3183 jne .LOP_IPUT_BOOLEAN_finish # no, already resolved 3184 movl rIBASE,OUT_ARG1(%esp) 3185 movl rSELF,rIBASE 3186 EXPORT_PC 3187 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 3188 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 3189 SPILL_TMP1(%ecx) # save obj pointer across call 3190 movl rIBASE,OUT_ARG0(%esp) # pass in method->clazz 3191 call dvmResolveInstField # ... to dvmResolveInstField 3192 UNSPILL_TMP1(%ecx) 3193 testl %eax,%eax # returns InstrField ptr 3194 jne .LOP_IPUT_BOOLEAN_finish 3195 jmp common_exceptionThrown 3196 3197.LOP_IPUT_BOOLEAN_finish: 3198 /* 3199 * Currently: 3200 * eax holds resolved field 3201 * ecx holds object 3202 * rINST holds A 3203 */ 3204 GET_VREG_R rINST rINST # rINST<- v[A] 3205 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 3206 testl %ecx,%ecx # object null? 3207 je common_errNullObject # object was null 3208 movb rINSTbl,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 3209 FETCH_INST_OPCODE 2 %ecx 3210 UNSPILL(rIBASE) 3211 ADVANCE_PC 2 3212 GOTO_NEXT_R %ecx 3213 3214 3215/* ------------------------------ */ 3216.L_OP_IPUT_BYTE: /* 0x5d */ 3217/* File: x86/OP_IPUT_BYTE.S */ 3218/* File: x86/OP_IPUT.S */ 3219 3220 /* 3221 * General 32-bit instance field put. 3222 * 3223 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 3224 */ 3225 /* op vA, vB, field@CCCC */ 3226 movl rSELF,%ecx 3227 SPILL (rIBASE) 3228 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 3229 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 3230 movzbl rINSTbl,%ecx # ecx<- BA 3231 sarl $4,%ecx # ecx<- B 3232 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 3233 andb $0xf,rINSTbl # rINST<- A 3234 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 3235 movl (%eax,rIBASE,4),%eax # resolved entry 3236 testl %eax,%eax # is resolved entry null? 3237 jne .LOP_IPUT_BYTE_finish # no, already resolved 3238 movl rIBASE,OUT_ARG1(%esp) 3239 movl rSELF,rIBASE 3240 EXPORT_PC 3241 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 3242 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 3243 SPILL_TMP1(%ecx) # save obj pointer across call 3244 movl rIBASE,OUT_ARG0(%esp) # pass in method->clazz 3245 call dvmResolveInstField # ... to dvmResolveInstField 3246 UNSPILL_TMP1(%ecx) 3247 testl %eax,%eax # returns InstrField ptr 3248 jne .LOP_IPUT_BYTE_finish 3249 jmp common_exceptionThrown 3250 3251.LOP_IPUT_BYTE_finish: 3252 /* 3253 * Currently: 3254 * eax holds resolved field 3255 * ecx holds object 3256 * rINST holds A 3257 */ 3258 GET_VREG_R rINST rINST # rINST<- v[A] 3259 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 3260 testl %ecx,%ecx # object null? 3261 je common_errNullObject # object was null 3262 movb rINSTbl,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 3263 FETCH_INST_OPCODE 2 %ecx 3264 UNSPILL(rIBASE) 3265 ADVANCE_PC 2 3266 GOTO_NEXT_R %ecx 3267 3268 3269/* ------------------------------ */ 3270.L_OP_IPUT_CHAR: /* 0x5e */ 3271/* File: x86/OP_IPUT_CHAR.S */ 3272/* File: x86/OP_IPUT.S */ 3273 3274 /* 3275 * General 32-bit instance field put. 3276 * 3277 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 3278 */ 3279 /* op vA, vB, field@CCCC */ 3280 movl rSELF,%ecx 3281 SPILL (rIBASE) 3282 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 3283 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 3284 movzbl rINSTbl,%ecx # ecx<- BA 3285 sarl $4,%ecx # ecx<- B 3286 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 3287 andb $0xf,rINSTbl # rINST<- A 3288 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 3289 movl (%eax,rIBASE,4),%eax # resolved entry 3290 testl %eax,%eax # is resolved entry null? 3291 jne .LOP_IPUT_CHAR_finish # no, already resolved 3292 movl rIBASE,OUT_ARG1(%esp) 3293 movl rSELF,rIBASE 3294 EXPORT_PC 3295 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 3296 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 3297 SPILL_TMP1(%ecx) # save obj pointer across call 3298 movl rIBASE,OUT_ARG0(%esp) # pass in method->clazz 3299 call dvmResolveInstField # ... to dvmResolveInstField 3300 UNSPILL_TMP1(%ecx) 3301 testl %eax,%eax # returns InstrField ptr 3302 jne .LOP_IPUT_CHAR_finish 3303 jmp common_exceptionThrown 3304 3305.LOP_IPUT_CHAR_finish: 3306 /* 3307 * Currently: 3308 * eax holds resolved field 3309 * ecx holds object 3310 * rINST holds A 3311 */ 3312 GET_VREG_R rINST rINST # rINST<- v[A] 3313 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 3314 testl %ecx,%ecx # object null? 3315 je common_errNullObject # object was null 3316 movw rINSTw,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 3317 FETCH_INST_OPCODE 2 %ecx 3318 UNSPILL(rIBASE) 3319 ADVANCE_PC 2 3320 GOTO_NEXT_R %ecx 3321 3322 3323/* ------------------------------ */ 3324.L_OP_IPUT_SHORT: /* 0x5f */ 3325/* File: x86/OP_IPUT_SHORT.S */ 3326/* File: x86/OP_IPUT.S */ 3327 3328 /* 3329 * General 32-bit instance field put. 3330 * 3331 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 3332 */ 3333 /* op vA, vB, field@CCCC */ 3334 movl rSELF,%ecx 3335 SPILL (rIBASE) 3336 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 3337 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 3338 movzbl rINSTbl,%ecx # ecx<- BA 3339 sarl $4,%ecx # ecx<- B 3340 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 3341 andb $0xf,rINSTbl # rINST<- A 3342 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 3343 movl (%eax,rIBASE,4),%eax # resolved entry 3344 testl %eax,%eax # is resolved entry null? 3345 jne .LOP_IPUT_SHORT_finish # no, already resolved 3346 movl rIBASE,OUT_ARG1(%esp) 3347 movl rSELF,rIBASE 3348 EXPORT_PC 3349 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 3350 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 3351 SPILL_TMP1(%ecx) # save obj pointer across call 3352 movl rIBASE,OUT_ARG0(%esp) # pass in method->clazz 3353 call dvmResolveInstField # ... to dvmResolveInstField 3354 UNSPILL_TMP1(%ecx) 3355 testl %eax,%eax # returns InstrField ptr 3356 jne .LOP_IPUT_SHORT_finish 3357 jmp common_exceptionThrown 3358 3359.LOP_IPUT_SHORT_finish: 3360 /* 3361 * Currently: 3362 * eax holds resolved field 3363 * ecx holds object 3364 * rINST holds A 3365 */ 3366 GET_VREG_R rINST rINST # rINST<- v[A] 3367 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 3368 testl %ecx,%ecx # object null? 3369 je common_errNullObject # object was null 3370 movw rINSTw,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 3371 FETCH_INST_OPCODE 2 %ecx 3372 UNSPILL(rIBASE) 3373 ADVANCE_PC 2 3374 GOTO_NEXT_R %ecx 3375 3376 3377/* ------------------------------ */ 3378.L_OP_SGET: /* 0x60 */ 3379/* File: x86/OP_SGET.S */ 3380 /* 3381 * General 32-bit SGET handler. 3382 * 3383 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 3384 */ 3385 /* op vAA, field@BBBB */ 3386 movl rSELF,%ecx 3387 movzwl 2(rPC),%eax # eax<- field ref BBBB 3388 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 3389 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 3390#if defined(WITH_JIT) 3391 movl %ecx, TMP_SPILL1(%ebp) 3392 lea (%ecx,%eax,4),%ecx 3393 movl %ecx, TMP_SPILL2(%ebp) 3394 movl TMP_SPILL1(%ebp), %ecx 3395#endif 3396 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 3397 testl %eax,%eax # resolved entry null? 3398 je .LOP_SGET_resolve # if not, make it so 3399.LOP_SGET_finish: # field ptr in eax 3400 movl offStaticField_value(%eax),%eax 3401 FETCH_INST_OPCODE 2 %ecx 3402 ADVANCE_PC 2 3403 SET_VREG %eax rINST 3404 GOTO_NEXT_R %ecx 3405 3406 /* 3407 * Go resolve the field 3408 */ 3409.LOP_SGET_resolve: 3410 movl rSELF,%ecx 3411 movzwl 2(rPC),%eax # eax<- field ref BBBB 3412 movl offThread_method(%ecx),%ecx # ecx<- current method 3413 EXPORT_PC # could throw, need to export 3414 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 3415 movl %eax,OUT_ARG1(%esp) 3416 movl %ecx,OUT_ARG0(%esp) 3417 SPILL(rIBASE) 3418 call dvmResolveStaticField # eax<- resolved StaticField ptr 3419 UNSPILL(rIBASE) 3420 testl %eax,%eax 3421 je common_exceptionThrown # no, handle exception 3422#if defined(WITH_JIT) 3423 movl TMP_SPILL2(%ebp), %ecx 3424 SPILL(rIBASE) 3425 call common_verifyField 3426 UNSPILL(rIBASE) 3427#endif 3428 jmp .LOP_SGET_finish # success, continue 3429 3430/* ------------------------------ */ 3431.L_OP_SGET_WIDE: /* 0x61 */ 3432/* File: x86/OP_SGET_WIDE.S */ 3433 /* 3434 * 64-bit SGET handler. 3435 * 3436 */ 3437 /* sget-wide vAA, field@BBBB */ 3438 movl rSELF,%ecx 3439 movzwl 2(rPC),%eax # eax<- field ref BBBB 3440 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 3441 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 3442#if defined(WITH_JIT) 3443 movl %ecx, TMP_SPILL1(%ebp) 3444 lea (%ecx,%eax,4),%ecx 3445 movl %ecx, TMP_SPILL2(%ebp) 3446 movl TMP_SPILL1(%ebp), %ecx 3447#endif 3448 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 3449 testl %eax,%eax # resolved entry null? 3450 je .LOP_SGET_WIDE_resolve # if not, make it so 3451.LOP_SGET_WIDE_finish: # field ptr in eax 3452 movl offStaticField_value(%eax),%ecx # ecx<- lsw 3453 movl 4+offStaticField_value(%eax),%eax # eax<- msw 3454 SET_VREG_WORD %ecx rINST 0 3455 FETCH_INST_OPCODE 2 %ecx 3456 SET_VREG_WORD %eax rINST 1 3457 ADVANCE_PC 2 3458 GOTO_NEXT_R %ecx 3459 3460 /* 3461 * Go resolve the field 3462 */ 3463.LOP_SGET_WIDE_resolve: 3464 movl rSELF,%ecx 3465 movzwl 2(rPC),%eax # eax<- field ref BBBB 3466 movl offThread_method(%ecx),%ecx # ecx<- current method 3467 EXPORT_PC # could throw, need to export 3468 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 3469 movl %eax,OUT_ARG1(%esp) 3470 movl %ecx,OUT_ARG0(%esp) 3471 SPILL(rIBASE) 3472 call dvmResolveStaticField # eax<- resolved StaticField ptr 3473 UNSPILL(rIBASE) 3474 testl %eax,%eax 3475 je common_exceptionThrown # no, handle exception 3476#if defined(WITH_JIT) 3477 movl TMP_SPILL2(%ebp), %ecx 3478 SPILL(rIBASE) 3479 call common_verifyField 3480 UNSPILL(rIBASE) 3481#endif 3482 jmp .LOP_SGET_WIDE_finish # success, continue 3483 3484/* ------------------------------ */ 3485.L_OP_SGET_OBJECT: /* 0x62 */ 3486/* File: x86/OP_SGET_OBJECT.S */ 3487/* File: x86/OP_SGET.S */ 3488 /* 3489 * General 32-bit SGET handler. 3490 * 3491 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 3492 */ 3493 /* op vAA, field@BBBB */ 3494 movl rSELF,%ecx 3495 movzwl 2(rPC),%eax # eax<- field ref BBBB 3496 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 3497 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 3498#if defined(WITH_JIT) 3499 movl %ecx, TMP_SPILL1(%ebp) 3500 lea (%ecx,%eax,4),%ecx 3501 movl %ecx, TMP_SPILL2(%ebp) 3502 movl TMP_SPILL1(%ebp), %ecx 3503#endif 3504 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 3505 testl %eax,%eax # resolved entry null? 3506 je .LOP_SGET_OBJECT_resolve # if not, make it so 3507.LOP_SGET_OBJECT_finish: # field ptr in eax 3508 movl offStaticField_value(%eax),%eax 3509 FETCH_INST_OPCODE 2 %ecx 3510 ADVANCE_PC 2 3511 SET_VREG %eax rINST 3512 GOTO_NEXT_R %ecx 3513 3514 /* 3515 * Go resolve the field 3516 */ 3517.LOP_SGET_OBJECT_resolve: 3518 movl rSELF,%ecx 3519 movzwl 2(rPC),%eax # eax<- field ref BBBB 3520 movl offThread_method(%ecx),%ecx # ecx<- current method 3521 EXPORT_PC # could throw, need to export 3522 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 3523 movl %eax,OUT_ARG1(%esp) 3524 movl %ecx,OUT_ARG0(%esp) 3525 SPILL(rIBASE) 3526 call dvmResolveStaticField # eax<- resolved StaticField ptr 3527 UNSPILL(rIBASE) 3528 testl %eax,%eax 3529 je common_exceptionThrown # no, handle exception 3530#if defined(WITH_JIT) 3531 movl TMP_SPILL2(%ebp), %ecx 3532 SPILL(rIBASE) 3533 call common_verifyField 3534 UNSPILL(rIBASE) 3535#endif 3536 jmp .LOP_SGET_OBJECT_finish # success, continue 3537 3538 3539/* ------------------------------ */ 3540.L_OP_SGET_BOOLEAN: /* 0x63 */ 3541/* File: x86/OP_SGET_BOOLEAN.S */ 3542/* File: x86/OP_SGET.S */ 3543 /* 3544 * General 32-bit SGET handler. 3545 * 3546 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 3547 */ 3548 /* op vAA, field@BBBB */ 3549 movl rSELF,%ecx 3550 movzwl 2(rPC),%eax # eax<- field ref BBBB 3551 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 3552 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 3553#if defined(WITH_JIT) 3554 movl %ecx, TMP_SPILL1(%ebp) 3555 lea (%ecx,%eax,4),%ecx 3556 movl %ecx, TMP_SPILL2(%ebp) 3557 movl TMP_SPILL1(%ebp), %ecx 3558#endif 3559 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 3560 testl %eax,%eax # resolved entry null? 3561 je .LOP_SGET_BOOLEAN_resolve # if not, make it so 3562.LOP_SGET_BOOLEAN_finish: # field ptr in eax 3563 movl offStaticField_value(%eax),%eax 3564 FETCH_INST_OPCODE 2 %ecx 3565 ADVANCE_PC 2 3566 SET_VREG %eax rINST 3567 GOTO_NEXT_R %ecx 3568 3569 /* 3570 * Go resolve the field 3571 */ 3572.LOP_SGET_BOOLEAN_resolve: 3573 movl rSELF,%ecx 3574 movzwl 2(rPC),%eax # eax<- field ref BBBB 3575 movl offThread_method(%ecx),%ecx # ecx<- current method 3576 EXPORT_PC # could throw, need to export 3577 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 3578 movl %eax,OUT_ARG1(%esp) 3579 movl %ecx,OUT_ARG0(%esp) 3580 SPILL(rIBASE) 3581 call dvmResolveStaticField # eax<- resolved StaticField ptr 3582 UNSPILL(rIBASE) 3583 testl %eax,%eax 3584 je common_exceptionThrown # no, handle exception 3585#if defined(WITH_JIT) 3586 movl TMP_SPILL2(%ebp), %ecx 3587 SPILL(rIBASE) 3588 call common_verifyField 3589 UNSPILL(rIBASE) 3590#endif 3591 jmp .LOP_SGET_BOOLEAN_finish # success, continue 3592 3593 3594/* ------------------------------ */ 3595.L_OP_SGET_BYTE: /* 0x64 */ 3596/* File: x86/OP_SGET_BYTE.S */ 3597/* File: x86/OP_SGET.S */ 3598 /* 3599 * General 32-bit SGET handler. 3600 * 3601 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 3602 */ 3603 /* op vAA, field@BBBB */ 3604 movl rSELF,%ecx 3605 movzwl 2(rPC),%eax # eax<- field ref BBBB 3606 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 3607 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 3608#if defined(WITH_JIT) 3609 movl %ecx, TMP_SPILL1(%ebp) 3610 lea (%ecx,%eax,4),%ecx 3611 movl %ecx, TMP_SPILL2(%ebp) 3612 movl TMP_SPILL1(%ebp), %ecx 3613#endif 3614 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 3615 testl %eax,%eax # resolved entry null? 3616 je .LOP_SGET_BYTE_resolve # if not, make it so 3617.LOP_SGET_BYTE_finish: # field ptr in eax 3618 movl offStaticField_value(%eax),%eax 3619 FETCH_INST_OPCODE 2 %ecx 3620 ADVANCE_PC 2 3621 SET_VREG %eax rINST 3622 GOTO_NEXT_R %ecx 3623 3624 /* 3625 * Go resolve the field 3626 */ 3627.LOP_SGET_BYTE_resolve: 3628 movl rSELF,%ecx 3629 movzwl 2(rPC),%eax # eax<- field ref BBBB 3630 movl offThread_method(%ecx),%ecx # ecx<- current method 3631 EXPORT_PC # could throw, need to export 3632 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 3633 movl %eax,OUT_ARG1(%esp) 3634 movl %ecx,OUT_ARG0(%esp) 3635 SPILL(rIBASE) 3636 call dvmResolveStaticField # eax<- resolved StaticField ptr 3637 UNSPILL(rIBASE) 3638 testl %eax,%eax 3639 je common_exceptionThrown # no, handle exception 3640#if defined(WITH_JIT) 3641 movl TMP_SPILL2(%ebp), %ecx 3642 SPILL(rIBASE) 3643 call common_verifyField 3644 UNSPILL(rIBASE) 3645#endif 3646 jmp .LOP_SGET_BYTE_finish # success, continue 3647 3648 3649/* ------------------------------ */ 3650.L_OP_SGET_CHAR: /* 0x65 */ 3651/* File: x86/OP_SGET_CHAR.S */ 3652/* File: x86/OP_SGET.S */ 3653 /* 3654 * General 32-bit SGET handler. 3655 * 3656 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 3657 */ 3658 /* op vAA, field@BBBB */ 3659 movl rSELF,%ecx 3660 movzwl 2(rPC),%eax # eax<- field ref BBBB 3661 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 3662 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 3663#if defined(WITH_JIT) 3664 movl %ecx, TMP_SPILL1(%ebp) 3665 lea (%ecx,%eax,4),%ecx 3666 movl %ecx, TMP_SPILL2(%ebp) 3667 movl TMP_SPILL1(%ebp), %ecx 3668#endif 3669 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 3670 testl %eax,%eax # resolved entry null? 3671 je .LOP_SGET_CHAR_resolve # if not, make it so 3672.LOP_SGET_CHAR_finish: # field ptr in eax 3673 movl offStaticField_value(%eax),%eax 3674 FETCH_INST_OPCODE 2 %ecx 3675 ADVANCE_PC 2 3676 SET_VREG %eax rINST 3677 GOTO_NEXT_R %ecx 3678 3679 /* 3680 * Go resolve the field 3681 */ 3682.LOP_SGET_CHAR_resolve: 3683 movl rSELF,%ecx 3684 movzwl 2(rPC),%eax # eax<- field ref BBBB 3685 movl offThread_method(%ecx),%ecx # ecx<- current method 3686 EXPORT_PC # could throw, need to export 3687 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 3688 movl %eax,OUT_ARG1(%esp) 3689 movl %ecx,OUT_ARG0(%esp) 3690 SPILL(rIBASE) 3691 call dvmResolveStaticField # eax<- resolved StaticField ptr 3692 UNSPILL(rIBASE) 3693 testl %eax,%eax 3694 je common_exceptionThrown # no, handle exception 3695#if defined(WITH_JIT) 3696 movl TMP_SPILL2(%ebp), %ecx 3697 SPILL(rIBASE) 3698 call common_verifyField 3699 UNSPILL(rIBASE) 3700#endif 3701 jmp .LOP_SGET_CHAR_finish # success, continue 3702 3703 3704/* ------------------------------ */ 3705.L_OP_SGET_SHORT: /* 0x66 */ 3706/* File: x86/OP_SGET_SHORT.S */ 3707/* File: x86/OP_SGET.S */ 3708 /* 3709 * General 32-bit SGET handler. 3710 * 3711 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 3712 */ 3713 /* op vAA, field@BBBB */ 3714 movl rSELF,%ecx 3715 movzwl 2(rPC),%eax # eax<- field ref BBBB 3716 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 3717 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 3718#if defined(WITH_JIT) 3719 movl %ecx, TMP_SPILL1(%ebp) 3720 lea (%ecx,%eax,4),%ecx 3721 movl %ecx, TMP_SPILL2(%ebp) 3722 movl TMP_SPILL1(%ebp), %ecx 3723#endif 3724 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 3725 testl %eax,%eax # resolved entry null? 3726 je .LOP_SGET_SHORT_resolve # if not, make it so 3727.LOP_SGET_SHORT_finish: # field ptr in eax 3728 movl offStaticField_value(%eax),%eax 3729 FETCH_INST_OPCODE 2 %ecx 3730 ADVANCE_PC 2 3731 SET_VREG %eax rINST 3732 GOTO_NEXT_R %ecx 3733 3734 /* 3735 * Go resolve the field 3736 */ 3737.LOP_SGET_SHORT_resolve: 3738 movl rSELF,%ecx 3739 movzwl 2(rPC),%eax # eax<- field ref BBBB 3740 movl offThread_method(%ecx),%ecx # ecx<- current method 3741 EXPORT_PC # could throw, need to export 3742 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 3743 movl %eax,OUT_ARG1(%esp) 3744 movl %ecx,OUT_ARG0(%esp) 3745 SPILL(rIBASE) 3746 call dvmResolveStaticField # eax<- resolved StaticField ptr 3747 UNSPILL(rIBASE) 3748 testl %eax,%eax 3749 je common_exceptionThrown # no, handle exception 3750#if defined(WITH_JIT) 3751 movl TMP_SPILL2(%ebp), %ecx 3752 SPILL(rIBASE) 3753 call common_verifyField 3754 UNSPILL(rIBASE) 3755#endif 3756 jmp .LOP_SGET_SHORT_finish # success, continue 3757 3758 3759/* ------------------------------ */ 3760.L_OP_SPUT: /* 0x67 */ 3761/* File: x86/OP_SPUT.S */ 3762 /* 3763 * General 32-bit SPUT handler. 3764 * 3765 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3766 */ 3767 /* op vAA, field@BBBB */ 3768 movl rSELF,%ecx 3769 movzwl 2(rPC),%eax # eax<- field ref BBBB 3770 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 3771 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 3772#if defined(WITH_JIT) 3773 movl %ecx, TMP_SPILL1(%ebp) 3774 lea (%ecx,%eax,4),%ecx 3775 movl %ecx, TMP_SPILL2(%ebp) 3776 movl TMP_SPILL1(%ebp), %ecx 3777#endif 3778 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 3779 testl %eax,%eax # resolved entry null? 3780 je .LOP_SPUT_resolve # if not, make it so 3781.LOP_SPUT_finish: # field ptr in eax 3782 GET_VREG_R rINST rINST 3783 FETCH_INST_OPCODE 2 %ecx 3784 ADVANCE_PC 2 3785 movl rINST,offStaticField_value(%eax) 3786 GOTO_NEXT_R %ecx 3787 3788 /* 3789 * Go resolve the field 3790 */ 3791.LOP_SPUT_resolve: 3792 movl rSELF,%ecx 3793 movzwl 2(rPC),%eax # eax<- field ref BBBB 3794 movl offThread_method(%ecx),%ecx # ecx<- current method 3795 EXPORT_PC # could throw, need to export 3796 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 3797 movl %eax,OUT_ARG1(%esp) 3798 movl %ecx,OUT_ARG0(%esp) 3799 SPILL(rIBASE) 3800 call dvmResolveStaticField # eax<- resolved StaticField ptr 3801 UNSPILL(rIBASE) 3802 testl %eax,%eax 3803 je common_exceptionThrown # no, handle exception 3804#if defined(WITH_JIT) 3805 movl TMP_SPILL2(%ebp), %ecx 3806 SPILL(rIBASE) 3807 call common_verifyField 3808 UNSPILL(rIBASE) 3809#endif 3810 jmp .LOP_SPUT_finish # success, continue 3811/* ------------------------------ */ 3812.L_OP_SPUT_WIDE: /* 0x68 */ 3813/* File: x86/OP_SPUT_WIDE.S */ 3814 /* 3815 * General 32-bit SPUT handler. 3816 * 3817 * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short 3818 */ 3819 /* op vAA, field@BBBB */ 3820 movl rSELF,%ecx 3821 movzwl 2(rPC),%eax # eax<- field ref BBBB 3822 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 3823 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 3824#if defined(WITH_JIT) 3825 movl %ecx, TMP_SPILL1(%ebp) 3826 lea (%ecx,%eax,4),%ecx 3827 movl %ecx, TMP_SPILL2(%ebp) 3828 movl TMP_SPILL1(%ebp), %ecx 3829#endif 3830 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 3831 testl %eax,%eax # resolved entry null? 3832 je .LOP_SPUT_WIDE_resolve # if not, make it so 3833.LOP_SPUT_WIDE_finish: # field ptr in eax 3834 GET_VREG_WORD %ecx rINST 0 # rINST<- lsw 3835 GET_VREG_WORD rINST rINST 1 # ecx<- msw 3836 movl %ecx,offStaticField_value(%eax) 3837 FETCH_INST_OPCODE 2 %ecx 3838 movl rINST,4+offStaticField_value(%eax) 3839 ADVANCE_PC 2 3840 GOTO_NEXT_R %ecx 3841 3842 /* 3843 * Go resolve the field 3844 */ 3845.LOP_SPUT_WIDE_resolve: 3846 movl rSELF,%ecx 3847 movzwl 2(rPC),%eax # eax<- field ref BBBB 3848 movl offThread_method(%ecx),%ecx # ecx<- current method 3849 EXPORT_PC # could throw, need to export 3850 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 3851 movl %eax,OUT_ARG1(%esp) 3852 movl %ecx,OUT_ARG0(%esp) 3853 SPILL(rIBASE) 3854 call dvmResolveStaticField # eax<- resolved StaticField ptr 3855 UNSPILL(rIBASE) 3856 testl %eax,%eax 3857 je common_exceptionThrown # no, handle exception 3858#if defined(WITH_JIT) 3859 movl TMP_SPILL2(%ebp), %ecx 3860 SPILL(rIBASE) 3861 call common_verifyField 3862 UNSPILL(rIBASE) 3863#endif 3864 jmp .LOP_SPUT_WIDE_finish # success, continue 3865 3866/* ------------------------------ */ 3867.L_OP_SPUT_OBJECT: /* 0x69 */ 3868/* File: x86/OP_SPUT_OBJECT.S */ 3869 /* 3870 * SPUT object handler. 3871 */ 3872 /* op vAA, field@BBBB */ 3873 movl rSELF,%ecx 3874 movzwl 2(rPC),%eax # eax<- field ref BBBB 3875 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 3876 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 3877#if defined(WITH_JIT) 3878 movl %ecx, TMP_SPILL1(%ebp) 3879 lea (%ecx,%eax,4),%ecx 3880 movl %ecx, TMP_SPILL2(%ebp) 3881 movl TMP_SPILL1(%ebp), %ecx 3882#endif 3883 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField 3884 testl %eax,%eax # resolved entry null? 3885 je .LOP_SPUT_OBJECT_resolve # if not, make it so 3886.LOP_SPUT_OBJECT_finish: # field ptr in eax 3887 movzbl rINSTbl,%ecx # ecx<- AA 3888 GET_VREG_R %ecx %ecx 3889 movl %ecx,offStaticField_value(%eax) # do the store 3890 testl %ecx,%ecx # stored null object ptr? 3891 je 1f # skip card mark if null 3892 movl rSELF,%ecx 3893 movl offField_clazz(%eax),%eax # eax<- method->clazz 3894 movl offThread_cardTable(%ecx),%ecx # get card table base 3895 shrl $GC_CARD_SHIFT,%eax # head to card number 3896 movb %cl,(%ecx,%eax) # mark card 38971: 3898 FETCH_INST_OPCODE 2 %ecx 3899 ADVANCE_PC 2 3900 GOTO_NEXT_R %ecx 3901 3902.LOP_SPUT_OBJECT_resolve: 3903 movl rSELF,%ecx 3904 movzwl 2(rPC),%eax # eax<- field ref BBBB 3905 movl offThread_method(%ecx),%ecx # ecx<- current method 3906 EXPORT_PC # could throw, need to export 3907 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 3908 movl %eax,OUT_ARG1(%esp) 3909 movl %ecx,OUT_ARG0(%esp) 3910 SPILL(rIBASE) 3911 call dvmResolveStaticField # eax<- resolved StaticField ptr 3912 UNSPILL(rIBASE) 3913 testl %eax,%eax 3914 je common_exceptionThrown # no, handle exception 3915#if defined(WITH_JIT) 3916 movl TMP_SPILL2(%ebp), %ecx 3917 SPILL(rIBASE) 3918 call common_verifyField 3919 UNSPILL(rIBASE) 3920#endif 3921 jmp .LOP_SPUT_OBJECT_finish # success, continue 3922 3923/* ------------------------------ */ 3924.L_OP_SPUT_BOOLEAN: /* 0x6a */ 3925/* File: x86/OP_SPUT_BOOLEAN.S */ 3926/* File: x86/OP_SPUT.S */ 3927 /* 3928 * General 32-bit SPUT handler. 3929 * 3930 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3931 */ 3932 /* op vAA, field@BBBB */ 3933 movl rSELF,%ecx 3934 movzwl 2(rPC),%eax # eax<- field ref BBBB 3935 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 3936 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 3937#if defined(WITH_JIT) 3938 movl %ecx, TMP_SPILL1(%ebp) 3939 lea (%ecx,%eax,4),%ecx 3940 movl %ecx, TMP_SPILL2(%ebp) 3941 movl TMP_SPILL1(%ebp), %ecx 3942#endif 3943 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 3944 testl %eax,%eax # resolved entry null? 3945 je .LOP_SPUT_BOOLEAN_resolve # if not, make it so 3946.LOP_SPUT_BOOLEAN_finish: # field ptr in eax 3947 GET_VREG_R rINST rINST 3948 FETCH_INST_OPCODE 2 %ecx 3949 ADVANCE_PC 2 3950 movl rINST,offStaticField_value(%eax) 3951 GOTO_NEXT_R %ecx 3952 3953 /* 3954 * Go resolve the field 3955 */ 3956.LOP_SPUT_BOOLEAN_resolve: 3957 movl rSELF,%ecx 3958 movzwl 2(rPC),%eax # eax<- field ref BBBB 3959 movl offThread_method(%ecx),%ecx # ecx<- current method 3960 EXPORT_PC # could throw, need to export 3961 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 3962 movl %eax,OUT_ARG1(%esp) 3963 movl %ecx,OUT_ARG0(%esp) 3964 SPILL(rIBASE) 3965 call dvmResolveStaticField # eax<- resolved StaticField ptr 3966 UNSPILL(rIBASE) 3967 testl %eax,%eax 3968 je common_exceptionThrown # no, handle exception 3969#if defined(WITH_JIT) 3970 movl TMP_SPILL2(%ebp), %ecx 3971 SPILL(rIBASE) 3972 call common_verifyField 3973 UNSPILL(rIBASE) 3974#endif 3975 jmp .LOP_SPUT_BOOLEAN_finish # success, continue 3976 3977/* ------------------------------ */ 3978.L_OP_SPUT_BYTE: /* 0x6b */ 3979/* File: x86/OP_SPUT_BYTE.S */ 3980/* File: x86/OP_SPUT.S */ 3981 /* 3982 * General 32-bit SPUT handler. 3983 * 3984 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3985 */ 3986 /* op vAA, field@BBBB */ 3987 movl rSELF,%ecx 3988 movzwl 2(rPC),%eax # eax<- field ref BBBB 3989 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 3990 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 3991#if defined(WITH_JIT) 3992 movl %ecx, TMP_SPILL1(%ebp) 3993 lea (%ecx,%eax,4),%ecx 3994 movl %ecx, TMP_SPILL2(%ebp) 3995 movl TMP_SPILL1(%ebp), %ecx 3996#endif 3997 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 3998 testl %eax,%eax # resolved entry null? 3999 je .LOP_SPUT_BYTE_resolve # if not, make it so 4000.LOP_SPUT_BYTE_finish: # field ptr in eax 4001 GET_VREG_R rINST rINST 4002 FETCH_INST_OPCODE 2 %ecx 4003 ADVANCE_PC 2 4004 movl rINST,offStaticField_value(%eax) 4005 GOTO_NEXT_R %ecx 4006 4007 /* 4008 * Go resolve the field 4009 */ 4010.LOP_SPUT_BYTE_resolve: 4011 movl rSELF,%ecx 4012 movzwl 2(rPC),%eax # eax<- field ref BBBB 4013 movl offThread_method(%ecx),%ecx # ecx<- current method 4014 EXPORT_PC # could throw, need to export 4015 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 4016 movl %eax,OUT_ARG1(%esp) 4017 movl %ecx,OUT_ARG0(%esp) 4018 SPILL(rIBASE) 4019 call dvmResolveStaticField # eax<- resolved StaticField ptr 4020 UNSPILL(rIBASE) 4021 testl %eax,%eax 4022 je common_exceptionThrown # no, handle exception 4023#if defined(WITH_JIT) 4024 movl TMP_SPILL2(%ebp), %ecx 4025 SPILL(rIBASE) 4026 call common_verifyField 4027 UNSPILL(rIBASE) 4028#endif 4029 jmp .LOP_SPUT_BYTE_finish # success, continue 4030 4031/* ------------------------------ */ 4032.L_OP_SPUT_CHAR: /* 0x6c */ 4033/* File: x86/OP_SPUT_CHAR.S */ 4034/* File: x86/OP_SPUT.S */ 4035 /* 4036 * General 32-bit SPUT handler. 4037 * 4038 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 4039 */ 4040 /* op vAA, field@BBBB */ 4041 movl rSELF,%ecx 4042 movzwl 2(rPC),%eax # eax<- field ref BBBB 4043 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 4044 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 4045#if defined(WITH_JIT) 4046 movl %ecx, TMP_SPILL1(%ebp) 4047 lea (%ecx,%eax,4),%ecx 4048 movl %ecx, TMP_SPILL2(%ebp) 4049 movl TMP_SPILL1(%ebp), %ecx 4050#endif 4051 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 4052 testl %eax,%eax # resolved entry null? 4053 je .LOP_SPUT_CHAR_resolve # if not, make it so 4054.LOP_SPUT_CHAR_finish: # field ptr in eax 4055 GET_VREG_R rINST rINST 4056 FETCH_INST_OPCODE 2 %ecx 4057 ADVANCE_PC 2 4058 movl rINST,offStaticField_value(%eax) 4059 GOTO_NEXT_R %ecx 4060 4061 /* 4062 * Go resolve the field 4063 */ 4064.LOP_SPUT_CHAR_resolve: 4065 movl rSELF,%ecx 4066 movzwl 2(rPC),%eax # eax<- field ref BBBB 4067 movl offThread_method(%ecx),%ecx # ecx<- current method 4068 EXPORT_PC # could throw, need to export 4069 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 4070 movl %eax,OUT_ARG1(%esp) 4071 movl %ecx,OUT_ARG0(%esp) 4072 SPILL(rIBASE) 4073 call dvmResolveStaticField # eax<- resolved StaticField ptr 4074 UNSPILL(rIBASE) 4075 testl %eax,%eax 4076 je common_exceptionThrown # no, handle exception 4077#if defined(WITH_JIT) 4078 movl TMP_SPILL2(%ebp), %ecx 4079 SPILL(rIBASE) 4080 call common_verifyField 4081 UNSPILL(rIBASE) 4082#endif 4083 jmp .LOP_SPUT_CHAR_finish # success, continue 4084 4085/* ------------------------------ */ 4086.L_OP_SPUT_SHORT: /* 0x6d */ 4087/* File: x86/OP_SPUT_SHORT.S */ 4088/* File: x86/OP_SPUT.S */ 4089 /* 4090 * General 32-bit SPUT handler. 4091 * 4092 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 4093 */ 4094 /* op vAA, field@BBBB */ 4095 movl rSELF,%ecx 4096 movzwl 2(rPC),%eax # eax<- field ref BBBB 4097 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 4098 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 4099#if defined(WITH_JIT) 4100 movl %ecx, TMP_SPILL1(%ebp) 4101 lea (%ecx,%eax,4),%ecx 4102 movl %ecx, TMP_SPILL2(%ebp) 4103 movl TMP_SPILL1(%ebp), %ecx 4104#endif 4105 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 4106 testl %eax,%eax # resolved entry null? 4107 je .LOP_SPUT_SHORT_resolve # if not, make it so 4108.LOP_SPUT_SHORT_finish: # field ptr in eax 4109 GET_VREG_R rINST rINST 4110 FETCH_INST_OPCODE 2 %ecx 4111 ADVANCE_PC 2 4112 movl rINST,offStaticField_value(%eax) 4113 GOTO_NEXT_R %ecx 4114 4115 /* 4116 * Go resolve the field 4117 */ 4118.LOP_SPUT_SHORT_resolve: 4119 movl rSELF,%ecx 4120 movzwl 2(rPC),%eax # eax<- field ref BBBB 4121 movl offThread_method(%ecx),%ecx # ecx<- current method 4122 EXPORT_PC # could throw, need to export 4123 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 4124 movl %eax,OUT_ARG1(%esp) 4125 movl %ecx,OUT_ARG0(%esp) 4126 SPILL(rIBASE) 4127 call dvmResolveStaticField # eax<- resolved StaticField ptr 4128 UNSPILL(rIBASE) 4129 testl %eax,%eax 4130 je common_exceptionThrown # no, handle exception 4131#if defined(WITH_JIT) 4132 movl TMP_SPILL2(%ebp), %ecx 4133 SPILL(rIBASE) 4134 call common_verifyField 4135 UNSPILL(rIBASE) 4136#endif 4137 jmp .LOP_SPUT_SHORT_finish # success, continue 4138 4139/* ------------------------------ */ 4140.L_OP_INVOKE_VIRTUAL: /* 0x6e */ 4141/* File: x86/OP_INVOKE_VIRTUAL.S */ 4142 4143 /* 4144 * Handle a virtual method call. 4145 * 4146 * for: invoke-virtual, invoke-virtual/range 4147 */ 4148 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 4149 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 4150 movl rSELF,%eax 4151 movzwl 2(rPC),%ecx # ecx<- BBBB 4152 movl offThread_methodClassDex(%eax),%eax # eax<- pDvmDex 4153 EXPORT_PC 4154 movl offDvmDex_pResMethods(%eax),%eax # eax<- pDvmDex->pResMethods 4155 movl (%eax,%ecx,4),%eax # eax<- resolved baseMethod 4156 testl %eax,%eax # already resolved? 4157 jne .LOP_INVOKE_VIRTUAL_continue # yes, continue 4158 movl rSELF,%eax 4159 movl %ecx,OUT_ARG1(%esp) # arg1<- ref 4160 movl offThread_method(%eax),%eax # eax<- self->method 4161 movl offMethod_clazz(%eax),%eax # ecx<- method->clazz 4162 movl %eax,OUT_ARG0(%esp) # arg0<- clazz 4163 movl $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags 4164 call dvmResolveMethod # eax<- call(clazz, ref, flags) 4165 testl %eax,%eax # got null? 4166 jne .LOP_INVOKE_VIRTUAL_continue # no, continue 4167 jmp common_exceptionThrown # yes, handle exception 4168 4169 /* At this point: 4170 * eax = resolved base method 4171 * ecx = scratch 4172 */ 4173.LOP_INVOKE_VIRTUAL_continue: 4174 movzwl 4(rPC),%ecx # ecx<- GFED or CCCC 4175 .if (!0) 4176 andl $0xf,%ecx # ecx<- D (or stays CCCC) 4177 .endif 4178 GET_VREG_R %ecx %ecx # ecx<- "this" 4179 movzwl offMethod_methodIndex(%eax),%eax # eax<- baseMethod->methodIndex 4180 testl %ecx,%ecx # null this? 4181 je common_errNullObject # go if so 4182 movl offObject_clazz(%ecx),%edx # edx<- thisPtr->clazz 4183 movl offClassObject_vtable(%edx),%edx # edx<- thisPtr->clazz->vtable 4184 movl (%edx,%eax,4),%eax # eax<- vtable[methodIndex] 4185 jmp common_invokeMethodNoRange 4186 4187/* ------------------------------ */ 4188.L_OP_INVOKE_SUPER: /* 0x6f */ 4189/* File: x86/OP_INVOKE_SUPER.S */ 4190 /* 4191 * Handle a "super" method call. 4192 * 4193 * for: invoke-super, invoke-super/range 4194 */ 4195 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 4196 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 4197 movl rSELF,rINST 4198 movzwl 2(rPC),%eax # eax<- BBBB 4199 movl offThread_methodClassDex(rINST),%ecx # ecx<- pDvmDex 4200 EXPORT_PC 4201 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 4202 movl (%ecx,%eax,4),%ecx # ecx<- resolved baseMethod 4203 movl offThread_method(rINST),%eax # eax<- method 4204 movzwl 4(rPC),rINST # rINST<- GFED or CCCC 4205 .if (!0) 4206 andl $0xf,rINST # rINST<- D (or stays CCCC) 4207 .endif 4208 GET_VREG_R %edx rINST # %edx<- "this" ptr 4209 testl %edx,%edx # null "this"? 4210 SPILL_TMP1(%edx) 4211 je common_errNullObject # yes, throw 4212 movl offMethod_clazz(%eax),%eax # eax<- method->clazz 4213 testl %ecx,%ecx # already resolved? 4214 je .LOP_INVOKE_SUPER_resolve 4215 /* 4216 * At this point: 4217 * ecx = resolved base method [r0] 4218 * eax = method->clazz [r9] 4219 */ 4220.LOP_INVOKE_SUPER_continue: 4221 movl offClassObject_super(%eax),%eax # eax<- method->clazz->super 4222 movzwl offMethod_methodIndex(%ecx),%edx # edx<- baseMthod->methodIndex 4223 cmpl offClassObject_vtableCount(%eax),%edx # compare(methodIndex,vtableCount) 4224 jae .LOP_INVOKE_SUPER_nsm # method not present in superclass 4225 movl offClassObject_vtable(%eax),%eax # eax<- ...clazz->super->vtable 4226 movl (%eax,%edx,4),%eax # eax<- vtable[methodIndex] 4227 UNSPILL_TMP1(%edx) 4228 movl %edx, %ecx 4229 jmp common_invokeMethodNoRange 4230 4231 4232 /* At this point: 4233 * ecx = null (needs to be resolved base method) 4234 * eax = method->clazz 4235 */ 4236.LOP_INVOKE_SUPER_resolve: 4237 SPILL_TMP2(%eax) # method->clazz 4238 movl %eax,OUT_ARG0(%esp) # arg0<- method->clazz 4239 movzwl 2(rPC),%ecx # ecx<- BBBB 4240 movl $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- resolver method type 4241 movl %ecx,OUT_ARG1(%esp) # arg1<- ref 4242 call dvmResolveMethod # eax<- call(clazz, ref, flags) 4243 testl %eax,%eax # got null? 4244 movl %eax,%ecx # ecx<- resolved base method 4245 UNSPILL_TMP2(%eax) # restore method->clazz 4246 jne .LOP_INVOKE_SUPER_continue # good to go - continue 4247 jmp common_exceptionThrown # handle exception 4248 4249 /* 4250 * Throw a NoSuchMethodError with the method name as the message. 4251 * ecx = resolved base method 4252 */ 4253.LOP_INVOKE_SUPER_nsm: 4254 movl offMethod_name(%ecx),%eax 4255 jmp common_errNoSuchMethod 4256 4257/* ------------------------------ */ 4258.L_OP_INVOKE_DIRECT: /* 0x70 */ 4259/* File: x86/OP_INVOKE_DIRECT.S */ 4260 /* 4261 * Handle a direct method call. 4262 * 4263 * (We could defer the "is 'this' pointer null" test to the common 4264 * method invocation code, and use a flag to indicate that static 4265 * calls don't count. If we do this as part of copying the arguments 4266 * out we could avoiding loading the first arg twice.) 4267 * 4268 * for: invoke-direct, invoke-direct/range 4269 */ 4270 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 4271 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 4272 movl rSELF,%ecx 4273 movzwl 2(rPC),%eax # eax<- BBBB 4274 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 4275 EXPORT_PC 4276 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 4277 movzwl 4(rPC),rIBASE # rIBASE<- GFED or CCCC 4278 movl (%ecx,%eax,4),%eax # eax<- resolved methodToCall 4279 .if (!0) 4280 andl $0xf,rIBASE # rIBASE<- D (or stays CCCC) 4281 .endif 4282 testl %eax,%eax # already resolved? 4283 GET_VREG_R %ecx rIBASE # ecx<- "this" ptr 4284 je .LOP_INVOKE_DIRECT_resolve # not resolved, do it now 4285.LOP_INVOKE_DIRECT_finish: 4286 testl %ecx,%ecx # null "this"? 4287 jne common_invokeMethodNoRange # no, continue on 4288 jmp common_errNullObject 4289 4290 /* 4291 * On entry: 4292 * TMP_SPILL <- "this" register 4293 * Things a bit ugly on this path, but it's the less 4294 * frequent one. We'll have to do some reloading. 4295 */ 4296.LOP_INVOKE_DIRECT_resolve: 4297 SPILL_TMP1(%ecx) 4298 movl rSELF,%ecx 4299 movl offThread_method(%ecx),%ecx # ecx<- self->method 4300 movzwl 2(rPC),%eax # reference (BBBB or CCCC) 4301 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 4302 movl $METHOD_DIRECT,OUT_ARG2(%esp) 4303 movl %eax,OUT_ARG1(%esp) 4304 movl %ecx,OUT_ARG0(%esp) 4305 call dvmResolveMethod # eax<- call(clazz, ref, flags) 4306 UNSPILL_TMP1(%ecx) 4307 testl %eax,%eax 4308 jne .LOP_INVOKE_DIRECT_finish 4309 jmp common_exceptionThrown 4310 4311/* ------------------------------ */ 4312.L_OP_INVOKE_STATIC: /* 0x71 */ 4313/* File: x86/OP_INVOKE_STATIC.S */ 4314 /* 4315 * Handle a static method call. 4316 * 4317 * for: invoke-static, invoke-static/range 4318 */ 4319 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 4320 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 4321 movl rSELF,%ecx 4322 movzwl 2(rPC),%eax # eax<- BBBB 4323 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 4324 EXPORT_PC 4325 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 4326#if defined(WITH_JIT) 4327 movl %edx, TMP_SPILL1(%ebp) 4328 lea (%ecx,%eax,4), %edx 4329 movl %edx, TMP_SPILL2(%ebp) 4330 movl TMP_SPILL1(%ebp), %edx 4331#endif 4332 movl (%ecx,%eax,4),%eax # eax<- resolved methodToCall 4333 movl $0, %ecx # make "this" null 4334 testl %eax,%eax 4335 jne common_invokeMethodNoRange 4336 4337 movl rSELF,%ecx 4338 movl offThread_method(%ecx),%ecx # ecx<- self->method 4339 movzwl 2(rPC),%eax 4340 movl offMethod_clazz(%ecx),%ecx# ecx<- method->clazz 4341 movl %eax,OUT_ARG1(%esp) # arg1<- BBBB 4342 movl %ecx,OUT_ARG0(%esp) # arg0<- clazz 4343 movl $METHOD_STATIC,%eax 4344 movl %eax,OUT_ARG2(%esp) # arg2<- flags 4345 SPILL(rIBASE) 4346 call dvmResolveMethod # call(clazz,ref,flags) 4347 UNSPILL(rIBASE) 4348 testl %eax,%eax # got null? 4349#if defined(WITH_JIT) 4350 movl TMP_SPILL1(%ebp), %edx 4351 movl rSELF,%ecx 4352 movzwl offThread_subMode(%ecx), %ecx 4353 je common_exceptionThrown # null, handle exception 4354 andl $kSubModeJitTraceBuild, %ecx # is trace under construction? 4355 movl $0, %ecx # make "this" null 4356 je common_invokeMethodNoRange # no (%eax=method, %ecx="this") 4357 movl TMP_SPILL2(%ebp), %edx 4358 cmpl $0, (%edx) # finished resolving 4359 movl TMP_SPILL1(%ebp), %edx 4360 jne common_invokeMethodNoRange # yes (%eax=method, %ecx="this") 4361 movl rSELF, %edx 4362 movl %edx, OUT_ARG0(%esp) 4363 movl rPC, OUT_ARG1(%esp) 4364 movl %eax, TMP_SPILL2(%ebp) 4365 movl %ecx, TMP_SPILL3(%ebp) 4366 SPILL(rIBASE) 4367 call dvmJitEndTraceSelect 4368 UNSPILL(rIBASE) 4369 movl TMP_SPILL1(%ebp), %edx 4370 movl TMP_SPILL2(%ebp), %eax 4371 movl TMP_SPILL3(%ebp), %ecx 4372 jmp common_invokeMethodNoRange 4373#else 4374 movl $0, %ecx # make "this" null 4375 jne common_invokeMethodNoRange 4376 jmp common_exceptionThrown 4377#endif 4378 4379 4380/* ------------------------------ */ 4381.L_OP_INVOKE_INTERFACE: /* 0x72 */ 4382/* File: x86/OP_INVOKE_INTERFACE.S */ 4383 /* 4384 * Handle an interface method call. 4385 * 4386 * for: invoke-interface, invoke-interface/range 4387 */ 4388 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 4389 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 4390 movzwl 4(rPC),%eax # eax<- FEDC or CCCC 4391 movl rSELF,%ecx 4392 .if (!0) 4393 andl $0xf,%eax # eax<- C (or stays CCCC) 4394 .endif 4395 GET_VREG_R %eax %eax # eax<- "this" 4396 EXPORT_PC 4397 testl %eax,%eax # null this? 4398 je common_errNullObject # yes, fail 4399 movl %eax, TMP_SPILL1(%ebp) 4400 movl offObject_clazz(%eax),%eax# eax<- thisPtr->clazz 4401 movl %eax,OUT_ARG0(%esp) # arg0<- class 4402 movl offThread_methodClassDex(%ecx),%eax # eax<- methodClassDex 4403 movl offThread_method(%ecx),%ecx # ecx<- method 4404 movl %eax,OUT_ARG3(%esp) # arg3<- dex 4405 movzwl 2(rPC),%eax # eax<- BBBB 4406 movl %ecx,OUT_ARG2(%esp) # arg2<- method 4407 movl %eax,OUT_ARG1(%esp) # arg1<- BBBB 4408 call dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex) 4409 testl %eax,%eax 4410 je common_exceptionThrown 4411 movl TMP_SPILL1(%ebp), %ecx 4412 jmp common_invokeMethodNoRange 4413 4414/* ------------------------------ */ 4415.L_OP_UNUSED_73: /* 0x73 */ 4416/* File: x86/OP_UNUSED_73.S */ 4417/* File: x86/unused.S */ 4418 jmp common_abort 4419 4420 4421/* ------------------------------ */ 4422.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 4423/* File: x86/OP_INVOKE_VIRTUAL_RANGE.S */ 4424/* File: x86/OP_INVOKE_VIRTUAL.S */ 4425 4426 /* 4427 * Handle a virtual method call. 4428 * 4429 * for: invoke-virtual, invoke-virtual/range 4430 */ 4431 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 4432 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 4433 movl rSELF,%eax 4434 movzwl 2(rPC),%ecx # ecx<- BBBB 4435 movl offThread_methodClassDex(%eax),%eax # eax<- pDvmDex 4436 EXPORT_PC 4437 movl offDvmDex_pResMethods(%eax),%eax # eax<- pDvmDex->pResMethods 4438 movl (%eax,%ecx,4),%eax # eax<- resolved baseMethod 4439 testl %eax,%eax # already resolved? 4440 jne .LOP_INVOKE_VIRTUAL_RANGE_continue # yes, continue 4441 movl rSELF,%eax 4442 movl %ecx,OUT_ARG1(%esp) # arg1<- ref 4443 movl offThread_method(%eax),%eax # eax<- self->method 4444 movl offMethod_clazz(%eax),%eax # ecx<- method->clazz 4445 movl %eax,OUT_ARG0(%esp) # arg0<- clazz 4446 movl $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags 4447 call dvmResolveMethod # eax<- call(clazz, ref, flags) 4448 testl %eax,%eax # got null? 4449 jne .LOP_INVOKE_VIRTUAL_RANGE_continue # no, continue 4450 jmp common_exceptionThrown # yes, handle exception 4451 4452 /* At this point: 4453 * eax = resolved base method 4454 * ecx = scratch 4455 */ 4456.LOP_INVOKE_VIRTUAL_RANGE_continue: 4457 movzwl 4(rPC),%ecx # ecx<- GFED or CCCC 4458 .if (!1) 4459 andl $0xf,%ecx # ecx<- D (or stays CCCC) 4460 .endif 4461 GET_VREG_R %ecx %ecx # ecx<- "this" 4462 movzwl offMethod_methodIndex(%eax),%eax # eax<- baseMethod->methodIndex 4463 testl %ecx,%ecx # null this? 4464 je common_errNullObject # go if so 4465 movl offObject_clazz(%ecx),%edx # edx<- thisPtr->clazz 4466 movl offClassObject_vtable(%edx),%edx # edx<- thisPtr->clazz->vtable 4467 movl (%edx,%eax,4),%eax # eax<- vtable[methodIndex] 4468 jmp common_invokeMethodRange 4469 4470 4471/* ------------------------------ */ 4472.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 4473/* File: x86/OP_INVOKE_SUPER_RANGE.S */ 4474/* File: x86/OP_INVOKE_SUPER.S */ 4475 /* 4476 * Handle a "super" method call. 4477 * 4478 * for: invoke-super, invoke-super/range 4479 */ 4480 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 4481 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 4482 movl rSELF,rINST 4483 movzwl 2(rPC),%eax # eax<- BBBB 4484 movl offThread_methodClassDex(rINST),%ecx # ecx<- pDvmDex 4485 EXPORT_PC 4486 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 4487 movl (%ecx,%eax,4),%ecx # ecx<- resolved baseMethod 4488 movl offThread_method(rINST),%eax # eax<- method 4489 movzwl 4(rPC),rINST # rINST<- GFED or CCCC 4490 .if (!1) 4491 andl $0xf,rINST # rINST<- D (or stays CCCC) 4492 .endif 4493 GET_VREG_R %edx rINST # %edx<- "this" ptr 4494 testl %edx,%edx # null "this"? 4495 SPILL_TMP1(%edx) 4496 je common_errNullObject # yes, throw 4497 movl offMethod_clazz(%eax),%eax # eax<- method->clazz 4498 testl %ecx,%ecx # already resolved? 4499 je .LOP_INVOKE_SUPER_RANGE_resolve 4500 /* 4501 * At this point: 4502 * ecx = resolved base method [r0] 4503 * eax = method->clazz [r9] 4504 */ 4505.LOP_INVOKE_SUPER_RANGE_continue: 4506 movl offClassObject_super(%eax),%eax # eax<- method->clazz->super 4507 movzwl offMethod_methodIndex(%ecx),%edx # edx<- baseMthod->methodIndex 4508 cmpl offClassObject_vtableCount(%eax),%edx # compare(methodIndex,vtableCount) 4509 jae .LOP_INVOKE_SUPER_RANGE_nsm # method not present in superclass 4510 movl offClassObject_vtable(%eax),%eax # eax<- ...clazz->super->vtable 4511 movl (%eax,%edx,4),%eax # eax<- vtable[methodIndex] 4512 UNSPILL_TMP1(%edx) 4513 movl %edx, %ecx 4514 jmp common_invokeMethodRange 4515 4516 4517 /* At this point: 4518 * ecx = null (needs to be resolved base method) 4519 * eax = method->clazz 4520 */ 4521.LOP_INVOKE_SUPER_RANGE_resolve: 4522 SPILL_TMP2(%eax) # method->clazz 4523 movl %eax,OUT_ARG0(%esp) # arg0<- method->clazz 4524 movzwl 2(rPC),%ecx # ecx<- BBBB 4525 movl $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- resolver method type 4526 movl %ecx,OUT_ARG1(%esp) # arg1<- ref 4527 call dvmResolveMethod # eax<- call(clazz, ref, flags) 4528 testl %eax,%eax # got null? 4529 movl %eax,%ecx # ecx<- resolved base method 4530 UNSPILL_TMP2(%eax) # restore method->clazz 4531 jne .LOP_INVOKE_SUPER_RANGE_continue # good to go - continue 4532 jmp common_exceptionThrown # handle exception 4533 4534 /* 4535 * Throw a NoSuchMethodError with the method name as the message. 4536 * ecx = resolved base method 4537 */ 4538.LOP_INVOKE_SUPER_RANGE_nsm: 4539 movl offMethod_name(%ecx),%eax 4540 jmp common_errNoSuchMethod 4541 4542 4543/* ------------------------------ */ 4544.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 4545/* File: x86/OP_INVOKE_DIRECT_RANGE.S */ 4546/* File: x86/OP_INVOKE_DIRECT.S */ 4547 /* 4548 * Handle a direct method call. 4549 * 4550 * (We could defer the "is 'this' pointer null" test to the common 4551 * method invocation code, and use a flag to indicate that static 4552 * calls don't count. If we do this as part of copying the arguments 4553 * out we could avoiding loading the first arg twice.) 4554 * 4555 * for: invoke-direct, invoke-direct/range 4556 */ 4557 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 4558 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 4559 movl rSELF,%ecx 4560 movzwl 2(rPC),%eax # eax<- BBBB 4561 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 4562 EXPORT_PC 4563 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 4564 movzwl 4(rPC),rIBASE # rIBASE<- GFED or CCCC 4565 movl (%ecx,%eax,4),%eax # eax<- resolved methodToCall 4566 .if (!1) 4567 andl $0xf,rIBASE # rIBASE<- D (or stays CCCC) 4568 .endif 4569 testl %eax,%eax # already resolved? 4570 GET_VREG_R %ecx rIBASE # ecx<- "this" ptr 4571 je .LOP_INVOKE_DIRECT_RANGE_resolve # not resolved, do it now 4572.LOP_INVOKE_DIRECT_RANGE_finish: 4573 testl %ecx,%ecx # null "this"? 4574 jne common_invokeMethodRange # no, continue on 4575 jmp common_errNullObject 4576 4577 /* 4578 * On entry: 4579 * TMP_SPILL <- "this" register 4580 * Things a bit ugly on this path, but it's the less 4581 * frequent one. We'll have to do some reloading. 4582 */ 4583.LOP_INVOKE_DIRECT_RANGE_resolve: 4584 SPILL_TMP1(%ecx) 4585 movl rSELF,%ecx 4586 movl offThread_method(%ecx),%ecx # ecx<- self->method 4587 movzwl 2(rPC),%eax # reference (BBBB or CCCC) 4588 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 4589 movl $METHOD_DIRECT,OUT_ARG2(%esp) 4590 movl %eax,OUT_ARG1(%esp) 4591 movl %ecx,OUT_ARG0(%esp) 4592 call dvmResolveMethod # eax<- call(clazz, ref, flags) 4593 UNSPILL_TMP1(%ecx) 4594 testl %eax,%eax 4595 jne .LOP_INVOKE_DIRECT_RANGE_finish 4596 jmp common_exceptionThrown 4597 4598 4599/* ------------------------------ */ 4600.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 4601/* File: x86/OP_INVOKE_STATIC_RANGE.S */ 4602/* File: x86/OP_INVOKE_STATIC.S */ 4603 /* 4604 * Handle a static method call. 4605 * 4606 * for: invoke-static, invoke-static/range 4607 */ 4608 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 4609 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 4610 movl rSELF,%ecx 4611 movzwl 2(rPC),%eax # eax<- BBBB 4612 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 4613 EXPORT_PC 4614 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 4615#if defined(WITH_JIT) 4616 movl %edx, TMP_SPILL1(%ebp) 4617 lea (%ecx,%eax,4), %edx 4618 movl %edx, TMP_SPILL2(%ebp) 4619 movl TMP_SPILL1(%ebp), %edx 4620#endif 4621 movl (%ecx,%eax,4),%eax # eax<- resolved methodToCall 4622 movl $0, %ecx # make "this" null 4623 testl %eax,%eax 4624 jne common_invokeMethodRange 4625 4626 movl rSELF,%ecx 4627 movl offThread_method(%ecx),%ecx # ecx<- self->method 4628 movzwl 2(rPC),%eax 4629 movl offMethod_clazz(%ecx),%ecx# ecx<- method->clazz 4630 movl %eax,OUT_ARG1(%esp) # arg1<- BBBB 4631 movl %ecx,OUT_ARG0(%esp) # arg0<- clazz 4632 movl $METHOD_STATIC,%eax 4633 movl %eax,OUT_ARG2(%esp) # arg2<- flags 4634 SPILL(rIBASE) 4635 call dvmResolveMethod # call(clazz,ref,flags) 4636 UNSPILL(rIBASE) 4637 testl %eax,%eax # got null? 4638#if defined(WITH_JIT) 4639 movl TMP_SPILL1(%ebp), %edx 4640 movl rSELF,%ecx 4641 movzwl offThread_subMode(%ecx), %ecx 4642 je common_exceptionThrown # null, handle exception 4643 andl $kSubModeJitTraceBuild, %ecx # is trace under construction? 4644 movl $0, %ecx # make "this" null 4645 je common_invokeMethodRange # no (%eax=method, %ecx="this") 4646 movl TMP_SPILL2(%ebp), %edx 4647 cmpl $0, (%edx) # finished resolving 4648 movl TMP_SPILL1(%ebp), %edx 4649 jne common_invokeMethodRange # yes (%eax=method, %ecx="this") 4650 movl rSELF, %edx 4651 movl %edx, OUT_ARG0(%esp) 4652 movl rPC, OUT_ARG1(%esp) 4653 movl %eax, TMP_SPILL2(%ebp) 4654 movl %ecx, TMP_SPILL3(%ebp) 4655 SPILL(rIBASE) 4656 call dvmJitEndTraceSelect 4657 UNSPILL(rIBASE) 4658 movl TMP_SPILL1(%ebp), %edx 4659 movl TMP_SPILL2(%ebp), %eax 4660 movl TMP_SPILL3(%ebp), %ecx 4661 jmp common_invokeMethodRange 4662#else 4663 movl $0, %ecx # make "this" null 4664 jne common_invokeMethodRange 4665 jmp common_exceptionThrown 4666#endif 4667 4668 4669 4670/* ------------------------------ */ 4671.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 4672/* File: x86/OP_INVOKE_INTERFACE_RANGE.S */ 4673/* File: x86/OP_INVOKE_INTERFACE.S */ 4674 /* 4675 * Handle an interface method call. 4676 * 4677 * for: invoke-interface, invoke-interface/range 4678 */ 4679 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 4680 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 4681 movzwl 4(rPC),%eax # eax<- FEDC or CCCC 4682 movl rSELF,%ecx 4683 .if (!1) 4684 andl $0xf,%eax # eax<- C (or stays CCCC) 4685 .endif 4686 GET_VREG_R %eax %eax # eax<- "this" 4687 EXPORT_PC 4688 testl %eax,%eax # null this? 4689 je common_errNullObject # yes, fail 4690 movl %eax, TMP_SPILL1(%ebp) 4691 movl offObject_clazz(%eax),%eax# eax<- thisPtr->clazz 4692 movl %eax,OUT_ARG0(%esp) # arg0<- class 4693 movl offThread_methodClassDex(%ecx),%eax # eax<- methodClassDex 4694 movl offThread_method(%ecx),%ecx # ecx<- method 4695 movl %eax,OUT_ARG3(%esp) # arg3<- dex 4696 movzwl 2(rPC),%eax # eax<- BBBB 4697 movl %ecx,OUT_ARG2(%esp) # arg2<- method 4698 movl %eax,OUT_ARG1(%esp) # arg1<- BBBB 4699 call dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex) 4700 testl %eax,%eax 4701 je common_exceptionThrown 4702 movl TMP_SPILL1(%ebp), %ecx 4703 jmp common_invokeMethodRange 4704 4705 4706/* ------------------------------ */ 4707.L_OP_UNUSED_79: /* 0x79 */ 4708/* File: x86/OP_UNUSED_79.S */ 4709/* File: x86/unused.S */ 4710 jmp common_abort 4711 4712 4713/* ------------------------------ */ 4714.L_OP_UNUSED_7A: /* 0x7a */ 4715/* File: x86/OP_UNUSED_7A.S */ 4716/* File: x86/unused.S */ 4717 jmp common_abort 4718 4719 4720/* ------------------------------ */ 4721.L_OP_NEG_INT: /* 0x7b */ 4722/* File: x86/OP_NEG_INT.S */ 4723/* File: x86/unop.S */ 4724 /* 4725 * Generic 32-bit unary operation. Provide an "instr" line that 4726 * specifies an instruction that performs "result = op eax". 4727 */ 4728 /* unop vA, vB */ 4729 movzbl rINSTbl,%ecx # ecx<- A+ 4730 sarl $4,rINST # rINST<- B 4731 GET_VREG_R %eax rINST # eax<- vB 4732 andb $0xf,%cl # ecx<- A 4733 4734 4735 negl %eax 4736 SET_VREG %eax %ecx 4737 FETCH_INST_OPCODE 1 %ecx 4738 ADVANCE_PC 1 4739 GOTO_NEXT_R %ecx 4740 4741 4742/* ------------------------------ */ 4743.L_OP_NOT_INT: /* 0x7c */ 4744/* File: x86/OP_NOT_INT.S */ 4745/* File: x86/unop.S */ 4746 /* 4747 * Generic 32-bit unary operation. Provide an "instr" line that 4748 * specifies an instruction that performs "result = op eax". 4749 */ 4750 /* unop vA, vB */ 4751 movzbl rINSTbl,%ecx # ecx<- A+ 4752 sarl $4,rINST # rINST<- B 4753 GET_VREG_R %eax rINST # eax<- vB 4754 andb $0xf,%cl # ecx<- A 4755 4756 4757 notl %eax 4758 SET_VREG %eax %ecx 4759 FETCH_INST_OPCODE 1 %ecx 4760 ADVANCE_PC 1 4761 GOTO_NEXT_R %ecx 4762 4763 4764/* ------------------------------ */ 4765.L_OP_NEG_LONG: /* 0x7d */ 4766/* File: x86/OP_NEG_LONG.S */ 4767 /* unop vA, vB */ 4768 movzbl rINSTbl,%ecx # ecx<- BA 4769 sarl $4,%ecx # ecx<- B 4770 andb $0xf,rINSTbl # rINST<- A 4771 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 4772 GET_VREG_WORD %ecx %ecx 1 # ecx<- v[B+1] 4773 negl %eax 4774 adcl $0,%ecx 4775 negl %ecx 4776 SET_VREG_WORD %eax rINST 0 # v[A+0]<- eax 4777 FETCH_INST_OPCODE 1 %eax 4778 SET_VREG_WORD %ecx rINST 1 # v[A+1]<- ecx 4779 ADVANCE_PC 1 4780 GOTO_NEXT_R %eax 4781 4782/* ------------------------------ */ 4783.L_OP_NOT_LONG: /* 0x7e */ 4784/* File: x86/OP_NOT_LONG.S */ 4785 /* unop vA, vB */ 4786 movzbl rINSTbl,%ecx # ecx<- BA 4787 sarl $4,%ecx # ecx<- B 4788 andb $0xf,rINSTbl # rINST<- A 4789 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 4790 GET_VREG_WORD %ecx %ecx 1 # ecx<- v[B+1] 4791 notl %eax 4792 notl %ecx 4793 SET_VREG_WORD %eax rINST 0 # v[A+0]<- eax 4794 FETCH_INST_OPCODE 1 %eax 4795 SET_VREG_WORD %ecx rINST 1 # v[A+1]<- ecx 4796 ADVANCE_PC 1 4797 GOTO_NEXT_R %eax 4798 4799/* ------------------------------ */ 4800.L_OP_NEG_FLOAT: /* 0x7f */ 4801/* File: x86/OP_NEG_FLOAT.S */ 4802/* File: x86/fpcvt.S */ 4803 /* 4804 * Generic 32-bit FP conversion operation. 4805 */ 4806 /* unop vA, vB */ 4807 movzbl rINSTbl,%ecx # ecx<- A+ 4808 sarl $4,rINST # rINST<- B 4809 flds (rFP,rINST,4) # %st0<- vB 4810 andb $0xf,%cl # ecx<- A 4811 fchs 4812 fstps (rFP,%ecx,4) # vA<- %st0 4813 FETCH_INST_OPCODE 1 %ecx 4814 ADVANCE_PC 1 4815 GOTO_NEXT_R %ecx 4816 4817 4818/* ------------------------------ */ 4819.L_OP_NEG_DOUBLE: /* 0x80 */ 4820/* File: x86/OP_NEG_DOUBLE.S */ 4821/* File: x86/fpcvt.S */ 4822 /* 4823 * Generic 32-bit FP conversion operation. 4824 */ 4825 /* unop vA, vB */ 4826 movzbl rINSTbl,%ecx # ecx<- A+ 4827 sarl $4,rINST # rINST<- B 4828 fldl (rFP,rINST,4) # %st0<- vB 4829 andb $0xf,%cl # ecx<- A 4830 fchs 4831 fstpl (rFP,%ecx,4) # vA<- %st0 4832 FETCH_INST_OPCODE 1 %ecx 4833 ADVANCE_PC 1 4834 GOTO_NEXT_R %ecx 4835 4836 4837/* ------------------------------ */ 4838.L_OP_INT_TO_LONG: /* 0x81 */ 4839/* File: x86/OP_INT_TO_LONG.S */ 4840 /* int to long vA, vB */ 4841 movzbl rINSTbl,%eax # eax<- +A 4842 sarl $4,%eax # eax<- B 4843 GET_VREG_R %eax %eax # eax<- vB 4844 andb $0xf,rINSTbl # rINST<- A 4845 SPILL(rIBASE) # cltd trashes rIBASE/edx 4846 cltd # rINST:eax<- sssssssBBBBBBBB 4847 SET_VREG_WORD rIBASE rINST 1 # v[A+1]<- rIBASE/rPC 4848 FETCH_INST_OPCODE 1 %ecx 4849 UNSPILL(rIBASE) 4850 SET_VREG_WORD %eax rINST 0 # v[A+0]<- %eax 4851 ADVANCE_PC 1 4852 GOTO_NEXT_R %ecx 4853 4854/* ------------------------------ */ 4855.L_OP_INT_TO_FLOAT: /* 0x82 */ 4856/* File: x86/OP_INT_TO_FLOAT.S */ 4857/* File: x86/fpcvt.S */ 4858 /* 4859 * Generic 32-bit FP conversion operation. 4860 */ 4861 /* unop vA, vB */ 4862 movzbl rINSTbl,%ecx # ecx<- A+ 4863 sarl $4,rINST # rINST<- B 4864 fildl (rFP,rINST,4) # %st0<- vB 4865 andb $0xf,%cl # ecx<- A 4866 4867 fstps (rFP,%ecx,4) # vA<- %st0 4868 FETCH_INST_OPCODE 1 %ecx 4869 ADVANCE_PC 1 4870 GOTO_NEXT_R %ecx 4871 4872 4873/* ------------------------------ */ 4874.L_OP_INT_TO_DOUBLE: /* 0x83 */ 4875/* File: x86/OP_INT_TO_DOUBLE.S */ 4876/* File: x86/fpcvt.S */ 4877 /* 4878 * Generic 32-bit FP conversion operation. 4879 */ 4880 /* unop vA, vB */ 4881 movzbl rINSTbl,%ecx # ecx<- A+ 4882 sarl $4,rINST # rINST<- B 4883 fildl (rFP,rINST,4) # %st0<- vB 4884 andb $0xf,%cl # ecx<- A 4885 4886 fstpl (rFP,%ecx,4) # vA<- %st0 4887 FETCH_INST_OPCODE 1 %ecx 4888 ADVANCE_PC 1 4889 GOTO_NEXT_R %ecx 4890 4891 4892/* ------------------------------ */ 4893.L_OP_LONG_TO_INT: /* 0x84 */ 4894/* File: x86/OP_LONG_TO_INT.S */ 4895/* we ignore the high word, making this equivalent to a 32-bit reg move */ 4896/* File: x86/OP_MOVE.S */ 4897 /* for move, move-object, long-to-int */ 4898 /* op vA, vB */ 4899 movzbl rINSTbl,%eax # eax<- BA 4900 andb $0xf,%al # eax<- A 4901 shrl $4,rINST # rINST<- B 4902 GET_VREG_R rINST rINST 4903 FETCH_INST_OPCODE 1 %ecx 4904 ADVANCE_PC 1 4905 SET_VREG rINST %eax # fp[A]<-fp[B] 4906 GOTO_NEXT_R %ecx 4907 4908 4909/* ------------------------------ */ 4910.L_OP_LONG_TO_FLOAT: /* 0x85 */ 4911/* File: x86/OP_LONG_TO_FLOAT.S */ 4912/* File: x86/fpcvt.S */ 4913 /* 4914 * Generic 32-bit FP conversion operation. 4915 */ 4916 /* unop vA, vB */ 4917 movzbl rINSTbl,%ecx # ecx<- A+ 4918 sarl $4,rINST # rINST<- B 4919 fildll (rFP,rINST,4) # %st0<- vB 4920 andb $0xf,%cl # ecx<- A 4921 4922 fstps (rFP,%ecx,4) # vA<- %st0 4923 FETCH_INST_OPCODE 1 %ecx 4924 ADVANCE_PC 1 4925 GOTO_NEXT_R %ecx 4926 4927 4928/* ------------------------------ */ 4929.L_OP_LONG_TO_DOUBLE: /* 0x86 */ 4930/* File: x86/OP_LONG_TO_DOUBLE.S */ 4931/* File: x86/fpcvt.S */ 4932 /* 4933 * Generic 32-bit FP conversion operation. 4934 */ 4935 /* unop vA, vB */ 4936 movzbl rINSTbl,%ecx # ecx<- A+ 4937 sarl $4,rINST # rINST<- B 4938 fildll (rFP,rINST,4) # %st0<- vB 4939 andb $0xf,%cl # ecx<- A 4940 4941 fstpl (rFP,%ecx,4) # vA<- %st0 4942 FETCH_INST_OPCODE 1 %ecx 4943 ADVANCE_PC 1 4944 GOTO_NEXT_R %ecx 4945 4946 4947/* ------------------------------ */ 4948.L_OP_FLOAT_TO_INT: /* 0x87 */ 4949/* File: x86/OP_FLOAT_TO_INT.S */ 4950/* File: x86/cvtfp_int.S */ 4951/* On fp to int conversions, Java requires that 4952 * if the result > maxint, it should be clamped to maxint. If it is less 4953 * than minint, it should be clamped to minint. If it is a nan, the result 4954 * should be zero. Further, the rounding mode is to truncate. This model 4955 * differs from what is delivered normally via the x86 fpu, so we have 4956 * to play some games. 4957 */ 4958 /* float/double to int/long vA, vB */ 4959 movzbl rINSTbl,%ecx # ecx<- A+ 4960 sarl $4,rINST # rINST<- B 4961 .if 0 4962 fldl (rFP,rINST,4) # %st0<- vB 4963 .else 4964 flds (rFP,rINST,4) # %st0<- vB 4965 .endif 4966 ftst 4967 fnstcw LOCAL0_OFFSET(%ebp) # remember original rounding mode 4968 movzwl LOCAL0_OFFSET(%ebp),%eax 4969 movb $0xc,%ah 4970 movw %ax,LOCAL0_OFFSET+2(%ebp) 4971 fldcw LOCAL0_OFFSET+2(%ebp) # set "to zero" rounding mode 4972 andb $0xf,%cl # ecx<- A 4973 .if 0 4974 fistpll (rFP,%ecx,4) # convert and store 4975 .else 4976 fistpl (rFP,%ecx,4) # convert and store 4977 .endif 4978 fldcw LOCAL0_OFFSET(%ebp) # restore previous rounding mode 4979 .if 0 4980 movl $0x80000000,%eax 4981 xorl 4(rFP,%ecx,4),%eax 4982 orl (rFP,%ecx,4),%eax 4983 .else 4984 cmpl $0x80000000,(rFP,%ecx,4) 4985 .endif 4986 je .LOP_FLOAT_TO_INT_special_case # fix up result 4987 4988.LOP_FLOAT_TO_INT_finish: 4989 FETCH_INST_OPCODE 1 %ecx 4990 ADVANCE_PC 1 4991 GOTO_NEXT_R %ecx 4992 4993.LOP_FLOAT_TO_INT_special_case: 4994 fnstsw %ax 4995 sahf 4996 jp .LOP_FLOAT_TO_INT_isNaN 4997 adcl $-1,(rFP,%ecx,4) 4998 .if 0 4999 adcl $-1,4(rFP,%ecx,4) 5000 .endif 5001 jmp .LOP_FLOAT_TO_INT_finish 5002.LOP_FLOAT_TO_INT_isNaN: 5003 movl $0,(rFP,%ecx,4) 5004 .if 0 5005 movl $0,4(rFP,%ecx,4) 5006 .endif 5007 jmp .LOP_FLOAT_TO_INT_finish 5008 5009 5010/* ------------------------------ */ 5011.L_OP_FLOAT_TO_LONG: /* 0x88 */ 5012/* File: x86/OP_FLOAT_TO_LONG.S */ 5013/* File: x86/cvtfp_int.S */ 5014/* On fp to int conversions, Java requires that 5015 * if the result > maxint, it should be clamped to maxint. If it is less 5016 * than minint, it should be clamped to minint. If it is a nan, the result 5017 * should be zero. Further, the rounding mode is to truncate. This model 5018 * differs from what is delivered normally via the x86 fpu, so we have 5019 * to play some games. 5020 */ 5021 /* float/double to int/long vA, vB */ 5022 movzbl rINSTbl,%ecx # ecx<- A+ 5023 sarl $4,rINST # rINST<- B 5024 .if 0 5025 fldl (rFP,rINST,4) # %st0<- vB 5026 .else 5027 flds (rFP,rINST,4) # %st0<- vB 5028 .endif 5029 ftst 5030 fnstcw LOCAL0_OFFSET(%ebp) # remember original rounding mode 5031 movzwl LOCAL0_OFFSET(%ebp),%eax 5032 movb $0xc,%ah 5033 movw %ax,LOCAL0_OFFSET+2(%ebp) 5034 fldcw LOCAL0_OFFSET+2(%ebp) # set "to zero" rounding mode 5035 andb $0xf,%cl # ecx<- A 5036 .if 1 5037 fistpll (rFP,%ecx,4) # convert and store 5038 .else 5039 fistpl (rFP,%ecx,4) # convert and store 5040 .endif 5041 fldcw LOCAL0_OFFSET(%ebp) # restore previous rounding mode 5042 .if 1 5043 movl $0x80000000,%eax 5044 xorl 4(rFP,%ecx,4),%eax 5045 orl (rFP,%ecx,4),%eax 5046 .else 5047 cmpl $0x80000000,(rFP,%ecx,4) 5048 .endif 5049 je .LOP_FLOAT_TO_LONG_special_case # fix up result 5050 5051.LOP_FLOAT_TO_LONG_finish: 5052 FETCH_INST_OPCODE 1 %ecx 5053 ADVANCE_PC 1 5054 GOTO_NEXT_R %ecx 5055 5056.LOP_FLOAT_TO_LONG_special_case: 5057 fnstsw %ax 5058 sahf 5059 jp .LOP_FLOAT_TO_LONG_isNaN 5060 adcl $-1,(rFP,%ecx,4) 5061 .if 1 5062 adcl $-1,4(rFP,%ecx,4) 5063 .endif 5064 jmp .LOP_FLOAT_TO_LONG_finish 5065.LOP_FLOAT_TO_LONG_isNaN: 5066 movl $0,(rFP,%ecx,4) 5067 .if 1 5068 movl $0,4(rFP,%ecx,4) 5069 .endif 5070 jmp .LOP_FLOAT_TO_LONG_finish 5071 5072 5073/* ------------------------------ */ 5074.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 5075/* File: x86/OP_FLOAT_TO_DOUBLE.S */ 5076/* File: x86/fpcvt.S */ 5077 /* 5078 * Generic 32-bit FP conversion operation. 5079 */ 5080 /* unop vA, vB */ 5081 movzbl rINSTbl,%ecx # ecx<- A+ 5082 sarl $4,rINST # rINST<- B 5083 flds (rFP,rINST,4) # %st0<- vB 5084 andb $0xf,%cl # ecx<- A 5085 5086 fstpl (rFP,%ecx,4) # vA<- %st0 5087 FETCH_INST_OPCODE 1 %ecx 5088 ADVANCE_PC 1 5089 GOTO_NEXT_R %ecx 5090 5091 5092/* ------------------------------ */ 5093.L_OP_DOUBLE_TO_INT: /* 0x8a */ 5094/* File: x86/OP_DOUBLE_TO_INT.S */ 5095/* File: x86/cvtfp_int.S */ 5096/* On fp to int conversions, Java requires that 5097 * if the result > maxint, it should be clamped to maxint. If it is less 5098 * than minint, it should be clamped to minint. If it is a nan, the result 5099 * should be zero. Further, the rounding mode is to truncate. This model 5100 * differs from what is delivered normally via the x86 fpu, so we have 5101 * to play some games. 5102 */ 5103 /* float/double to int/long vA, vB */ 5104 movzbl rINSTbl,%ecx # ecx<- A+ 5105 sarl $4,rINST # rINST<- B 5106 .if 1 5107 fldl (rFP,rINST,4) # %st0<- vB 5108 .else 5109 flds (rFP,rINST,4) # %st0<- vB 5110 .endif 5111 ftst 5112 fnstcw LOCAL0_OFFSET(%ebp) # remember original rounding mode 5113 movzwl LOCAL0_OFFSET(%ebp),%eax 5114 movb $0xc,%ah 5115 movw %ax,LOCAL0_OFFSET+2(%ebp) 5116 fldcw LOCAL0_OFFSET+2(%ebp) # set "to zero" rounding mode 5117 andb $0xf,%cl # ecx<- A 5118 .if 0 5119 fistpll (rFP,%ecx,4) # convert and store 5120 .else 5121 fistpl (rFP,%ecx,4) # convert and store 5122 .endif 5123 fldcw LOCAL0_OFFSET(%ebp) # restore previous rounding mode 5124 .if 0 5125 movl $0x80000000,%eax 5126 xorl 4(rFP,%ecx,4),%eax 5127 orl (rFP,%ecx,4),%eax 5128 .else 5129 cmpl $0x80000000,(rFP,%ecx,4) 5130 .endif 5131 je .LOP_DOUBLE_TO_INT_special_case # fix up result 5132 5133.LOP_DOUBLE_TO_INT_finish: 5134 FETCH_INST_OPCODE 1 %ecx 5135 ADVANCE_PC 1 5136 GOTO_NEXT_R %ecx 5137 5138.LOP_DOUBLE_TO_INT_special_case: 5139 fnstsw %ax 5140 sahf 5141 jp .LOP_DOUBLE_TO_INT_isNaN 5142 adcl $-1,(rFP,%ecx,4) 5143 .if 0 5144 adcl $-1,4(rFP,%ecx,4) 5145 .endif 5146 jmp .LOP_DOUBLE_TO_INT_finish 5147.LOP_DOUBLE_TO_INT_isNaN: 5148 movl $0,(rFP,%ecx,4) 5149 .if 0 5150 movl $0,4(rFP,%ecx,4) 5151 .endif 5152 jmp .LOP_DOUBLE_TO_INT_finish 5153 5154 5155/* ------------------------------ */ 5156.L_OP_DOUBLE_TO_LONG: /* 0x8b */ 5157/* File: x86/OP_DOUBLE_TO_LONG.S */ 5158/* File: x86/cvtfp_int.S */ 5159/* On fp to int conversions, Java requires that 5160 * if the result > maxint, it should be clamped to maxint. If it is less 5161 * than minint, it should be clamped to minint. If it is a nan, the result 5162 * should be zero. Further, the rounding mode is to truncate. This model 5163 * differs from what is delivered normally via the x86 fpu, so we have 5164 * to play some games. 5165 */ 5166 /* float/double to int/long vA, vB */ 5167 movzbl rINSTbl,%ecx # ecx<- A+ 5168 sarl $4,rINST # rINST<- B 5169 .if 1 5170 fldl (rFP,rINST,4) # %st0<- vB 5171 .else 5172 flds (rFP,rINST,4) # %st0<- vB 5173 .endif 5174 ftst 5175 fnstcw LOCAL0_OFFSET(%ebp) # remember original rounding mode 5176 movzwl LOCAL0_OFFSET(%ebp),%eax 5177 movb $0xc,%ah 5178 movw %ax,LOCAL0_OFFSET+2(%ebp) 5179 fldcw LOCAL0_OFFSET+2(%ebp) # set "to zero" rounding mode 5180 andb $0xf,%cl # ecx<- A 5181 .if 1 5182 fistpll (rFP,%ecx,4) # convert and store 5183 .else 5184 fistpl (rFP,%ecx,4) # convert and store 5185 .endif 5186 fldcw LOCAL0_OFFSET(%ebp) # restore previous rounding mode 5187 .if 1 5188 movl $0x80000000,%eax 5189 xorl 4(rFP,%ecx,4),%eax 5190 orl (rFP,%ecx,4),%eax 5191 .else 5192 cmpl $0x80000000,(rFP,%ecx,4) 5193 .endif 5194 je .LOP_DOUBLE_TO_LONG_special_case # fix up result 5195 5196.LOP_DOUBLE_TO_LONG_finish: 5197 FETCH_INST_OPCODE 1 %ecx 5198 ADVANCE_PC 1 5199 GOTO_NEXT_R %ecx 5200 5201.LOP_DOUBLE_TO_LONG_special_case: 5202 fnstsw %ax 5203 sahf 5204 jp .LOP_DOUBLE_TO_LONG_isNaN 5205 adcl $-1,(rFP,%ecx,4) 5206 .if 1 5207 adcl $-1,4(rFP,%ecx,4) 5208 .endif 5209 jmp .LOP_DOUBLE_TO_LONG_finish 5210.LOP_DOUBLE_TO_LONG_isNaN: 5211 movl $0,(rFP,%ecx,4) 5212 .if 1 5213 movl $0,4(rFP,%ecx,4) 5214 .endif 5215 jmp .LOP_DOUBLE_TO_LONG_finish 5216 5217 5218/* ------------------------------ */ 5219.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 5220/* File: x86/OP_DOUBLE_TO_FLOAT.S */ 5221/* File: x86/fpcvt.S */ 5222 /* 5223 * Generic 32-bit FP conversion operation. 5224 */ 5225 /* unop vA, vB */ 5226 movzbl rINSTbl,%ecx # ecx<- A+ 5227 sarl $4,rINST # rINST<- B 5228 fldl (rFP,rINST,4) # %st0<- vB 5229 andb $0xf,%cl # ecx<- A 5230 5231 fstps (rFP,%ecx,4) # vA<- %st0 5232 FETCH_INST_OPCODE 1 %ecx 5233 ADVANCE_PC 1 5234 GOTO_NEXT_R %ecx 5235 5236 5237/* ------------------------------ */ 5238.L_OP_INT_TO_BYTE: /* 0x8d */ 5239/* File: x86/OP_INT_TO_BYTE.S */ 5240/* File: x86/unop.S */ 5241 /* 5242 * Generic 32-bit unary operation. Provide an "instr" line that 5243 * specifies an instruction that performs "result = op eax". 5244 */ 5245 /* unop vA, vB */ 5246 movzbl rINSTbl,%ecx # ecx<- A+ 5247 sarl $4,rINST # rINST<- B 5248 GET_VREG_R %eax rINST # eax<- vB 5249 andb $0xf,%cl # ecx<- A 5250 5251 5252 movsbl %al,%eax 5253 SET_VREG %eax %ecx 5254 FETCH_INST_OPCODE 1 %ecx 5255 ADVANCE_PC 1 5256 GOTO_NEXT_R %ecx 5257 5258 5259/* ------------------------------ */ 5260.L_OP_INT_TO_CHAR: /* 0x8e */ 5261/* File: x86/OP_INT_TO_CHAR.S */ 5262/* File: x86/unop.S */ 5263 /* 5264 * Generic 32-bit unary operation. Provide an "instr" line that 5265 * specifies an instruction that performs "result = op eax". 5266 */ 5267 /* unop vA, vB */ 5268 movzbl rINSTbl,%ecx # ecx<- A+ 5269 sarl $4,rINST # rINST<- B 5270 GET_VREG_R %eax rINST # eax<- vB 5271 andb $0xf,%cl # ecx<- A 5272 5273 5274 movzwl %ax,%eax 5275 SET_VREG %eax %ecx 5276 FETCH_INST_OPCODE 1 %ecx 5277 ADVANCE_PC 1 5278 GOTO_NEXT_R %ecx 5279 5280 5281/* ------------------------------ */ 5282.L_OP_INT_TO_SHORT: /* 0x8f */ 5283/* File: x86/OP_INT_TO_SHORT.S */ 5284/* File: x86/unop.S */ 5285 /* 5286 * Generic 32-bit unary operation. Provide an "instr" line that 5287 * specifies an instruction that performs "result = op eax". 5288 */ 5289 /* unop vA, vB */ 5290 movzbl rINSTbl,%ecx # ecx<- A+ 5291 sarl $4,rINST # rINST<- B 5292 GET_VREG_R %eax rINST # eax<- vB 5293 andb $0xf,%cl # ecx<- A 5294 5295 5296 movswl %ax,%eax 5297 SET_VREG %eax %ecx 5298 FETCH_INST_OPCODE 1 %ecx 5299 ADVANCE_PC 1 5300 GOTO_NEXT_R %ecx 5301 5302 5303/* ------------------------------ */ 5304.L_OP_ADD_INT: /* 0x90 */ 5305/* File: x86/OP_ADD_INT.S */ 5306/* File: x86/binop.S */ 5307 /* 5308 * Generic 32-bit binary operation. Provide an "instr" line that 5309 * specifies an instruction that performs "result = eax op (rFP,%ecx,4)". 5310 * This could be an x86 instruction or a function call. (If the result 5311 * comes back in a register other than eax, you can override "result".) 5312 * 5313 * For: add-int, sub-int, and-int, or-int, 5314 * xor-int, shl-int, shr-int, ushr-int 5315 */ 5316 /* binop vAA, vBB, vCC */ 5317 movzbl 2(rPC),%eax # eax<- BB 5318 movzbl 3(rPC),%ecx # ecx<- CC 5319 GET_VREG_R %eax %eax # eax<- vBB 5320 addl (rFP,%ecx,4),%eax # ex: addl (rFP,%ecx,4),%eax 5321 SET_VREG %eax rINST 5322 FETCH_INST_OPCODE 2 %ecx 5323 ADVANCE_PC 2 5324 GOTO_NEXT_R %ecx 5325 5326 5327/* ------------------------------ */ 5328.L_OP_SUB_INT: /* 0x91 */ 5329/* File: x86/OP_SUB_INT.S */ 5330/* File: x86/binop.S */ 5331 /* 5332 * Generic 32-bit binary operation. Provide an "instr" line that 5333 * specifies an instruction that performs "result = eax op (rFP,%ecx,4)". 5334 * This could be an x86 instruction or a function call. (If the result 5335 * comes back in a register other than eax, you can override "result".) 5336 * 5337 * For: add-int, sub-int, and-int, or-int, 5338 * xor-int, shl-int, shr-int, ushr-int 5339 */ 5340 /* binop vAA, vBB, vCC */ 5341 movzbl 2(rPC),%eax # eax<- BB 5342 movzbl 3(rPC),%ecx # ecx<- CC 5343 GET_VREG_R %eax %eax # eax<- vBB 5344 subl (rFP,%ecx,4),%eax # ex: addl (rFP,%ecx,4),%eax 5345 SET_VREG %eax rINST 5346 FETCH_INST_OPCODE 2 %ecx 5347 ADVANCE_PC 2 5348 GOTO_NEXT_R %ecx 5349 5350 5351/* ------------------------------ */ 5352.L_OP_MUL_INT: /* 0x92 */ 5353/* File: x86/OP_MUL_INT.S */ 5354 /* 5355 * 32-bit binary multiplication. 5356 */ 5357 /* mul vAA, vBB, vCC */ 5358 movzbl 2(rPC),%eax # eax<- BB 5359 movzbl 3(rPC),%ecx # ecx<- CC 5360 GET_VREG_R %eax %eax # eax<- vBB 5361 SPILL(rIBASE) 5362 imull (rFP,%ecx,4),%eax # trashes rIBASE/edx 5363 UNSPILL(rIBASE) 5364 FETCH_INST_OPCODE 2 %ecx 5365 ADVANCE_PC 2 5366 SET_VREG %eax rINST 5367 GOTO_NEXT_R %ecx 5368 5369/* ------------------------------ */ 5370.L_OP_DIV_INT: /* 0x93 */ 5371/* File: x86/OP_DIV_INT.S */ 5372/* File: x86/bindiv.S */ 5373 5374 /* 5375 * 32-bit binary div/rem operation. Handles special case of op0=minint and 5376 * op1=-1. 5377 */ 5378 /* binop vAA, vBB, vCC */ 5379 movzbl 2(rPC),%eax # eax<- BB 5380 movzbl 3(rPC),%ecx # ecx<- CC 5381 GET_VREG_R %eax %eax # eax<- vBB 5382 GET_VREG_R %ecx %ecx # eax<- vBB 5383 SPILL(rIBASE) 5384 cmpl $0,%ecx 5385 je common_errDivideByZero 5386 cmpl $-1,%ecx 5387 jne .LOP_DIV_INT_continue_div 5388 cmpl $0x80000000,%eax 5389 jne .LOP_DIV_INT_continue_div 5390 movl $0x80000000,%eax 5391 SET_VREG %eax rINST 5392 UNSPILL(rIBASE) 5393 FETCH_INST_OPCODE 2 %ecx 5394 ADVANCE_PC 2 5395 GOTO_NEXT_R %ecx 5396 5397.LOP_DIV_INT_continue_div: 5398 cltd 5399 idivl %ecx 5400 SET_VREG %eax rINST 5401 UNSPILL(rIBASE) 5402 FETCH_INST_OPCODE 2 %ecx 5403 ADVANCE_PC 2 5404 GOTO_NEXT_R %ecx 5405 5406 5407/* ------------------------------ */ 5408.L_OP_REM_INT: /* 0x94 */ 5409/* File: x86/OP_REM_INT.S */ 5410/* File: x86/bindiv.S */ 5411 5412 /* 5413 * 32-bit binary div/rem operation. Handles special case of op0=minint and 5414 * op1=-1. 5415 */ 5416 /* binop vAA, vBB, vCC */ 5417 movzbl 2(rPC),%eax # eax<- BB 5418 movzbl 3(rPC),%ecx # ecx<- CC 5419 GET_VREG_R %eax %eax # eax<- vBB 5420 GET_VREG_R %ecx %ecx # eax<- vBB 5421 SPILL(rIBASE) 5422 cmpl $0,%ecx 5423 je common_errDivideByZero 5424 cmpl $-1,%ecx 5425 jne .LOP_REM_INT_continue_div 5426 cmpl $0x80000000,%eax 5427 jne .LOP_REM_INT_continue_div 5428 movl $0,rIBASE 5429 SET_VREG rIBASE rINST 5430 UNSPILL(rIBASE) 5431 FETCH_INST_OPCODE 2 %ecx 5432 ADVANCE_PC 2 5433 GOTO_NEXT_R %ecx 5434 5435.LOP_REM_INT_continue_div: 5436 cltd 5437 idivl %ecx 5438 SET_VREG rIBASE rINST 5439 UNSPILL(rIBASE) 5440 FETCH_INST_OPCODE 2 %ecx 5441 ADVANCE_PC 2 5442 GOTO_NEXT_R %ecx 5443 5444 5445/* ------------------------------ */ 5446.L_OP_AND_INT: /* 0x95 */ 5447/* File: x86/OP_AND_INT.S */ 5448/* File: x86/binop.S */ 5449 /* 5450 * Generic 32-bit binary operation. Provide an "instr" line that 5451 * specifies an instruction that performs "result = eax op (rFP,%ecx,4)". 5452 * This could be an x86 instruction or a function call. (If the result 5453 * comes back in a register other than eax, you can override "result".) 5454 * 5455 * For: add-int, sub-int, and-int, or-int, 5456 * xor-int, shl-int, shr-int, ushr-int 5457 */ 5458 /* binop vAA, vBB, vCC */ 5459 movzbl 2(rPC),%eax # eax<- BB 5460 movzbl 3(rPC),%ecx # ecx<- CC 5461 GET_VREG_R %eax %eax # eax<- vBB 5462 andl (rFP,%ecx,4),%eax # ex: addl (rFP,%ecx,4),%eax 5463 SET_VREG %eax rINST 5464 FETCH_INST_OPCODE 2 %ecx 5465 ADVANCE_PC 2 5466 GOTO_NEXT_R %ecx 5467 5468 5469/* ------------------------------ */ 5470.L_OP_OR_INT: /* 0x96 */ 5471/* File: x86/OP_OR_INT.S */ 5472/* File: x86/binop.S */ 5473 /* 5474 * Generic 32-bit binary operation. Provide an "instr" line that 5475 * specifies an instruction that performs "result = eax op (rFP,%ecx,4)". 5476 * This could be an x86 instruction or a function call. (If the result 5477 * comes back in a register other than eax, you can override "result".) 5478 * 5479 * For: add-int, sub-int, and-int, or-int, 5480 * xor-int, shl-int, shr-int, ushr-int 5481 */ 5482 /* binop vAA, vBB, vCC */ 5483 movzbl 2(rPC),%eax # eax<- BB 5484 movzbl 3(rPC),%ecx # ecx<- CC 5485 GET_VREG_R %eax %eax # eax<- vBB 5486 orl (rFP,%ecx,4),%eax # ex: addl (rFP,%ecx,4),%eax 5487 SET_VREG %eax rINST 5488 FETCH_INST_OPCODE 2 %ecx 5489 ADVANCE_PC 2 5490 GOTO_NEXT_R %ecx 5491 5492 5493/* ------------------------------ */ 5494.L_OP_XOR_INT: /* 0x97 */ 5495/* File: x86/OP_XOR_INT.S */ 5496/* File: x86/binop.S */ 5497 /* 5498 * Generic 32-bit binary operation. Provide an "instr" line that 5499 * specifies an instruction that performs "result = eax op (rFP,%ecx,4)". 5500 * This could be an x86 instruction or a function call. (If the result 5501 * comes back in a register other than eax, you can override "result".) 5502 * 5503 * For: add-int, sub-int, and-int, or-int, 5504 * xor-int, shl-int, shr-int, ushr-int 5505 */ 5506 /* binop vAA, vBB, vCC */ 5507 movzbl 2(rPC),%eax # eax<- BB 5508 movzbl 3(rPC),%ecx # ecx<- CC 5509 GET_VREG_R %eax %eax # eax<- vBB 5510 xorl (rFP,%ecx,4),%eax # ex: addl (rFP,%ecx,4),%eax 5511 SET_VREG %eax rINST 5512 FETCH_INST_OPCODE 2 %ecx 5513 ADVANCE_PC 2 5514 GOTO_NEXT_R %ecx 5515 5516 5517/* ------------------------------ */ 5518.L_OP_SHL_INT: /* 0x98 */ 5519/* File: x86/OP_SHL_INT.S */ 5520/* File: x86/binop1.S */ 5521 /* 5522 * Generic 32-bit binary operation in which both operands loaded to 5523 * registers (op0 in eax, op1 in ecx). 5524 */ 5525 /* binop vAA, vBB, vCC */ 5526 movzbl 2(rPC),%eax # eax<- BB 5527 movzbl 3(rPC),%ecx # ecx<- CC 5528 GET_VREG_R %eax %eax # eax<- vBB 5529 GET_VREG_R %ecx %ecx # eax<- vBB 5530 sall %cl,%eax # ex: addl %ecx,%eax 5531 SET_VREG %eax rINST 5532 FETCH_INST_OPCODE 2 %ecx 5533 ADVANCE_PC 2 5534 GOTO_NEXT_R %ecx 5535 5536 5537/* ------------------------------ */ 5538.L_OP_SHR_INT: /* 0x99 */ 5539/* File: x86/OP_SHR_INT.S */ 5540/* File: x86/binop1.S */ 5541 /* 5542 * Generic 32-bit binary operation in which both operands loaded to 5543 * registers (op0 in eax, op1 in ecx). 5544 */ 5545 /* binop vAA, vBB, vCC */ 5546 movzbl 2(rPC),%eax # eax<- BB 5547 movzbl 3(rPC),%ecx # ecx<- CC 5548 GET_VREG_R %eax %eax # eax<- vBB 5549 GET_VREG_R %ecx %ecx # eax<- vBB 5550 sarl %cl,%eax # ex: addl %ecx,%eax 5551 SET_VREG %eax rINST 5552 FETCH_INST_OPCODE 2 %ecx 5553 ADVANCE_PC 2 5554 GOTO_NEXT_R %ecx 5555 5556 5557/* ------------------------------ */ 5558.L_OP_USHR_INT: /* 0x9a */ 5559/* File: x86/OP_USHR_INT.S */ 5560/* File: x86/binop1.S */ 5561 /* 5562 * Generic 32-bit binary operation in which both operands loaded to 5563 * registers (op0 in eax, op1 in ecx). 5564 */ 5565 /* binop vAA, vBB, vCC */ 5566 movzbl 2(rPC),%eax # eax<- BB 5567 movzbl 3(rPC),%ecx # ecx<- CC 5568 GET_VREG_R %eax %eax # eax<- vBB 5569 GET_VREG_R %ecx %ecx # eax<- vBB 5570 shrl %cl,%eax # ex: addl %ecx,%eax 5571 SET_VREG %eax rINST 5572 FETCH_INST_OPCODE 2 %ecx 5573 ADVANCE_PC 2 5574 GOTO_NEXT_R %ecx 5575 5576 5577/* ------------------------------ */ 5578.L_OP_ADD_LONG: /* 0x9b */ 5579/* File: x86/OP_ADD_LONG.S */ 5580/* File: x86/binopWide.S */ 5581 /* 5582 * Generic 64-bit binary operation. 5583 */ 5584 /* binop vAA, vBB, vCC */ 5585 5586 movzbl 2(rPC),%eax # eax<- BB 5587 movzbl 3(rPC),%ecx # ecx<- CC 5588 SPILL(rIBASE) # save rIBASE 5589 GET_VREG_WORD rIBASE %eax 0 # rIBASE<- v[BB+0] 5590 GET_VREG_WORD %eax %eax 1 # eax<- v[BB+1] 5591 addl (rFP,%ecx,4),rIBASE # ex: addl (rFP,%ecx,4),rIBASE 5592 adcl 4(rFP,%ecx,4),%eax # ex: adcl 4(rFP,%ecx,4),%eax 5593 SET_VREG_WORD rIBASE rINST 0 # v[AA+0] <- rIBASE 5594 FETCH_INST_OPCODE 2 %ecx 5595 UNSPILL(rIBASE) # restore rIBASE 5596 SET_VREG_WORD %eax rINST 1 # v[AA+1] <- eax 5597 ADVANCE_PC 2 5598 GOTO_NEXT_R %ecx 5599 5600 5601/* ------------------------------ */ 5602.L_OP_SUB_LONG: /* 0x9c */ 5603/* File: x86/OP_SUB_LONG.S */ 5604/* File: x86/binopWide.S */ 5605 /* 5606 * Generic 64-bit binary operation. 5607 */ 5608 /* binop vAA, vBB, vCC */ 5609 5610 movzbl 2(rPC),%eax # eax<- BB 5611 movzbl 3(rPC),%ecx # ecx<- CC 5612 SPILL(rIBASE) # save rIBASE 5613 GET_VREG_WORD rIBASE %eax 0 # rIBASE<- v[BB+0] 5614 GET_VREG_WORD %eax %eax 1 # eax<- v[BB+1] 5615 subl (rFP,%ecx,4),rIBASE # ex: addl (rFP,%ecx,4),rIBASE 5616 sbbl 4(rFP,%ecx,4),%eax # ex: adcl 4(rFP,%ecx,4),%eax 5617 SET_VREG_WORD rIBASE rINST 0 # v[AA+0] <- rIBASE 5618 FETCH_INST_OPCODE 2 %ecx 5619 UNSPILL(rIBASE) # restore rIBASE 5620 SET_VREG_WORD %eax rINST 1 # v[AA+1] <- eax 5621 ADVANCE_PC 2 5622 GOTO_NEXT_R %ecx 5623 5624 5625/* ------------------------------ */ 5626.L_OP_MUL_LONG: /* 0x9d */ 5627/* File: x86/OP_MUL_LONG.S */ 5628 /* 5629 * Signed 64-bit integer multiply. 5630 * 5631 * We could definately use more free registers for 5632 * this code. We spill rINSTw (ebx), 5633 * giving us eax, ebc, ecx and edx as computational 5634 * temps. On top of that, we'll spill edi (rFP) 5635 * for use as the vB pointer and esi (rPC) for use 5636 * as the vC pointer. Yuck. 5637 */ 5638 /* mul-long vAA, vBB, vCC */ 5639 movzbl 2(rPC),%eax # eax<- B 5640 movzbl 3(rPC),%ecx # ecx<- C 5641 SPILL_TMP2(%esi) # save Dalvik PC 5642 SPILL(rFP) 5643 SPILL(rINST) 5644 SPILL(rIBASE) 5645 leal (rFP,%eax,4),%esi # esi<- &v[B] 5646 leal (rFP,%ecx,4),rFP # rFP<- &v[C] 5647 movl 4(%esi),%ecx # ecx<- Bmsw 5648 imull (rFP),%ecx # ecx<- (Bmsw*Clsw) 5649 movl 4(rFP),%eax # eax<- Cmsw 5650 imull (%esi),%eax # eax<- (Cmsw*Blsw) 5651 addl %eax,%ecx # ecx<- (Bmsw*Clsw)+(Cmsw*Blsw) 5652 movl (rFP),%eax # eax<- Clsw 5653 mull (%esi) # eax<- (Clsw*Alsw) 5654 UNSPILL(rINST) 5655 UNSPILL(rFP) 5656 leal (%ecx,rIBASE),rIBASE # full result now in rIBASE:%eax 5657 UNSPILL_TMP2(%esi) # Restore Dalvik PC 5658 FETCH_INST_OPCODE 2 %ecx # Fetch next instruction 5659 movl rIBASE,4(rFP,rINST,4)# v[B+1]<- rIBASE 5660 UNSPILL(rIBASE) 5661 movl %eax,(rFP,rINST,4) # v[B]<- %eax 5662 ADVANCE_PC 2 5663 GOTO_NEXT_R %ecx 5664 5665/* ------------------------------ */ 5666.L_OP_DIV_LONG: /* 0x9e */ 5667/* File: x86/OP_DIV_LONG.S */ 5668 /* div vAA, vBB, vCC */ 5669 movzbl 3(rPC),%eax # eax<- CC 5670 movzbl 2(rPC),%ecx # ecx<- BB 5671 SPILL(rIBASE) # save rIBASE/%edx 5672 GET_VREG_WORD rIBASE %eax 0 5673 GET_VREG_WORD %eax %eax 1 5674 movl rIBASE,OUT_ARG2(%esp) 5675 testl %eax,%eax 5676 je .LOP_DIV_LONG_check_zero 5677 cmpl $-1,%eax 5678 je .LOP_DIV_LONG_check_neg1 5679.LOP_DIV_LONG_notSpecial: 5680 GET_VREG_WORD rIBASE %ecx 0 5681 GET_VREG_WORD %ecx %ecx 1 5682.LOP_DIV_LONG_notSpecial1: 5683 movl %eax,OUT_ARG3(%esp) 5684 movl rIBASE,OUT_ARG0(%esp) 5685 movl %ecx,OUT_ARG1(%esp) 5686 call __divdi3 5687.LOP_DIV_LONG_finish: 5688 SET_VREG_WORD rIBASE rINST 1 5689 UNSPILL(rIBASE) # restore rIBASE/%edx 5690 SET_VREG_WORD %eax rINST 0 5691 FETCH_INST_OPCODE 2 %ecx 5692 ADVANCE_PC 2 5693 GOTO_NEXT_R %ecx 5694 5695.LOP_DIV_LONG_check_zero: 5696 testl rIBASE,rIBASE 5697 jne .LOP_DIV_LONG_notSpecial 5698 jmp common_errDivideByZero 5699.LOP_DIV_LONG_check_neg1: 5700 testl rIBASE,%eax 5701 jne .LOP_DIV_LONG_notSpecial 5702 GET_VREG_WORD rIBASE %ecx 0 5703 GET_VREG_WORD %ecx %ecx 1 5704 testl rIBASE,rIBASE 5705 jne .LOP_DIV_LONG_notSpecial1 5706 cmpl $0x80000000,%ecx 5707 jne .LOP_DIV_LONG_notSpecial1 5708 /* minint / -1, return minint on div, 0 on rem */ 5709 xorl %eax,%eax 5710 movl $0x80000000,rIBASE 5711 jmp .LOP_DIV_LONG_finish 5712 5713/* ------------------------------ */ 5714.L_OP_REM_LONG: /* 0x9f */ 5715/* File: x86/OP_REM_LONG.S */ 5716/* File: x86/OP_DIV_LONG.S */ 5717 /* div vAA, vBB, vCC */ 5718 movzbl 3(rPC),%eax # eax<- CC 5719 movzbl 2(rPC),%ecx # ecx<- BB 5720 SPILL(rIBASE) # save rIBASE/%edx 5721 GET_VREG_WORD rIBASE %eax 0 5722 GET_VREG_WORD %eax %eax 1 5723 movl rIBASE,OUT_ARG2(%esp) 5724 testl %eax,%eax 5725 je .LOP_REM_LONG_check_zero 5726 cmpl $-1,%eax 5727 je .LOP_REM_LONG_check_neg1 5728.LOP_REM_LONG_notSpecial: 5729 GET_VREG_WORD rIBASE %ecx 0 5730 GET_VREG_WORD %ecx %ecx 1 5731.LOP_REM_LONG_notSpecial1: 5732 movl %eax,OUT_ARG3(%esp) 5733 movl rIBASE,OUT_ARG0(%esp) 5734 movl %ecx,OUT_ARG1(%esp) 5735 call __moddi3 5736.LOP_REM_LONG_finish: 5737 SET_VREG_WORD rIBASE rINST 1 5738 UNSPILL(rIBASE) # restore rIBASE/%edx 5739 SET_VREG_WORD %eax rINST 0 5740 FETCH_INST_OPCODE 2 %ecx 5741 ADVANCE_PC 2 5742 GOTO_NEXT_R %ecx 5743 5744.LOP_REM_LONG_check_zero: 5745 testl rIBASE,rIBASE 5746 jne .LOP_REM_LONG_notSpecial 5747 jmp common_errDivideByZero 5748.LOP_REM_LONG_check_neg1: 5749 testl rIBASE,%eax 5750 jne .LOP_REM_LONG_notSpecial 5751 GET_VREG_WORD rIBASE %ecx 0 5752 GET_VREG_WORD %ecx %ecx 1 5753 testl rIBASE,rIBASE 5754 jne .LOP_REM_LONG_notSpecial1 5755 cmpl $0x80000000,%ecx 5756 jne .LOP_REM_LONG_notSpecial1 5757 /* minint / -1, return minint on div, 0 on rem */ 5758 xorl %eax,%eax 5759 movl $0,rIBASE 5760 jmp .LOP_REM_LONG_finish 5761 5762 5763/* ------------------------------ */ 5764.L_OP_AND_LONG: /* 0xa0 */ 5765/* File: x86/OP_AND_LONG.S */ 5766/* File: x86/binopWide.S */ 5767 /* 5768 * Generic 64-bit binary operation. 5769 */ 5770 /* binop vAA, vBB, vCC */ 5771 5772 movzbl 2(rPC),%eax # eax<- BB 5773 movzbl 3(rPC),%ecx # ecx<- CC 5774 SPILL(rIBASE) # save rIBASE 5775 GET_VREG_WORD rIBASE %eax 0 # rIBASE<- v[BB+0] 5776 GET_VREG_WORD %eax %eax 1 # eax<- v[BB+1] 5777 andl (rFP,%ecx,4),rIBASE # ex: addl (rFP,%ecx,4),rIBASE 5778 andl 4(rFP,%ecx,4),%eax # ex: adcl 4(rFP,%ecx,4),%eax 5779 SET_VREG_WORD rIBASE rINST 0 # v[AA+0] <- rIBASE 5780 FETCH_INST_OPCODE 2 %ecx 5781 UNSPILL(rIBASE) # restore rIBASE 5782 SET_VREG_WORD %eax rINST 1 # v[AA+1] <- eax 5783 ADVANCE_PC 2 5784 GOTO_NEXT_R %ecx 5785 5786 5787/* ------------------------------ */ 5788.L_OP_OR_LONG: /* 0xa1 */ 5789/* File: x86/OP_OR_LONG.S */ 5790/* File: x86/binopWide.S */ 5791 /* 5792 * Generic 64-bit binary operation. 5793 */ 5794 /* binop vAA, vBB, vCC */ 5795 5796 movzbl 2(rPC),%eax # eax<- BB 5797 movzbl 3(rPC),%ecx # ecx<- CC 5798 SPILL(rIBASE) # save rIBASE 5799 GET_VREG_WORD rIBASE %eax 0 # rIBASE<- v[BB+0] 5800 GET_VREG_WORD %eax %eax 1 # eax<- v[BB+1] 5801 orl (rFP,%ecx,4),rIBASE # ex: addl (rFP,%ecx,4),rIBASE 5802 orl 4(rFP,%ecx,4),%eax # ex: adcl 4(rFP,%ecx,4),%eax 5803 SET_VREG_WORD rIBASE rINST 0 # v[AA+0] <- rIBASE 5804 FETCH_INST_OPCODE 2 %ecx 5805 UNSPILL(rIBASE) # restore rIBASE 5806 SET_VREG_WORD %eax rINST 1 # v[AA+1] <- eax 5807 ADVANCE_PC 2 5808 GOTO_NEXT_R %ecx 5809 5810 5811/* ------------------------------ */ 5812.L_OP_XOR_LONG: /* 0xa2 */ 5813/* File: x86/OP_XOR_LONG.S */ 5814/* File: x86/binopWide.S */ 5815 /* 5816 * Generic 64-bit binary operation. 5817 */ 5818 /* binop vAA, vBB, vCC */ 5819 5820 movzbl 2(rPC),%eax # eax<- BB 5821 movzbl 3(rPC),%ecx # ecx<- CC 5822 SPILL(rIBASE) # save rIBASE 5823 GET_VREG_WORD rIBASE %eax 0 # rIBASE<- v[BB+0] 5824 GET_VREG_WORD %eax %eax 1 # eax<- v[BB+1] 5825 xorl (rFP,%ecx,4),rIBASE # ex: addl (rFP,%ecx,4),rIBASE 5826 xorl 4(rFP,%ecx,4),%eax # ex: adcl 4(rFP,%ecx,4),%eax 5827 SET_VREG_WORD rIBASE rINST 0 # v[AA+0] <- rIBASE 5828 FETCH_INST_OPCODE 2 %ecx 5829 UNSPILL(rIBASE) # restore rIBASE 5830 SET_VREG_WORD %eax rINST 1 # v[AA+1] <- eax 5831 ADVANCE_PC 2 5832 GOTO_NEXT_R %ecx 5833 5834 5835/* ------------------------------ */ 5836.L_OP_SHL_LONG: /* 0xa3 */ 5837/* File: x86/OP_SHL_LONG.S */ 5838 /* 5839 * Long integer shift. This is different from the generic 32/64-bit 5840 * binary operations because vAA/vBB are 64-bit but vCC (the shift 5841 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 5842 * 6 bits of the shift distance. x86 shifts automatically mask off 5843 * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31 5844 * case specially. 5845 */ 5846 /* shl-long vAA, vBB, vCC */ 5847 /* ecx gets shift count */ 5848 /* Need to spill rINST */ 5849 /* rINSTw gets AA */ 5850 movzbl 2(rPC),%eax # eax<- BB 5851 movzbl 3(rPC),%ecx # ecx<- CC 5852 SPILL(rIBASE) 5853 GET_VREG_WORD rIBASE %eax 1 # ecx<- v[BB+1] 5854 GET_VREG_R %ecx %ecx # ecx<- vCC 5855 GET_VREG_WORD %eax %eax 0 # eax<- v[BB+0] 5856 shldl %eax,rIBASE 5857 sall %cl,%eax 5858 testb $32,%cl 5859 je 2f 5860 movl %eax,rIBASE 5861 xorl %eax,%eax 58622: 5863 SET_VREG_WORD rIBASE rINST 1 # v[AA+1]<- rIBASE 5864 FETCH_INST_OPCODE 2 %ecx 5865 UNSPILL(rIBASE) 5866 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- %eax 5867 ADVANCE_PC 2 5868 GOTO_NEXT_R %ecx 5869 5870/* ------------------------------ */ 5871.L_OP_SHR_LONG: /* 0xa4 */ 5872/* File: x86/OP_SHR_LONG.S */ 5873 /* 5874 * Long integer shift. This is different from the generic 32/64-bit 5875 * binary operations because vAA/vBB are 64-bit but vCC (the shift 5876 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 5877 * 6 bits of the shift distance. x86 shifts automatically mask off 5878 * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31 5879 * case specially. 5880 */ 5881 /* shr-long vAA, vBB, vCC */ 5882 /* ecx gets shift count */ 5883 /* Need to spill rIBASE */ 5884 /* rINSTw gets AA */ 5885 movzbl 2(rPC),%eax # eax<- BB 5886 movzbl 3(rPC),%ecx # ecx<- CC 5887 SPILL(rIBASE) 5888 GET_VREG_WORD rIBASE %eax 1 # rIBASE<- v[BB+1] 5889 GET_VREG_R %ecx %ecx # ecx<- vCC 5890 GET_VREG_WORD %eax %eax 0 # eax<- v[BB+0] 5891 shrdl rIBASE,%eax 5892 sarl %cl,rIBASE 5893 testb $32,%cl 5894 je 2f 5895 movl rIBASE,%eax 5896 sarl $31,rIBASE 58972: 5898 SET_VREG_WORD rIBASE rINST 1 # v[AA+1]<- rIBASE 5899 FETCH_INST_OPCODE 2 %ecx 5900 UNSPILL(rIBASE) 5901 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- eax 5902 ADVANCE_PC 2 5903 GOTO_NEXT_R %ecx 5904 5905/* ------------------------------ */ 5906.L_OP_USHR_LONG: /* 0xa5 */ 5907/* File: x86/OP_USHR_LONG.S */ 5908 /* 5909 * Long integer shift. This is different from the generic 32/64-bit 5910 * binary operations because vAA/vBB are 64-bit but vCC (the shift 5911 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 5912 * 6 bits of the shift distance. x86 shifts automatically mask off 5913 * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31 5914 * case specially. 5915 */ 5916 /* shr-long vAA, vBB, vCC */ 5917 /* ecx gets shift count */ 5918 /* Need to spill rIBASE */ 5919 /* rINSTw gets AA */ 5920 movzbl 2(rPC),%eax # eax<- BB 5921 movzbl 3(rPC),%ecx # ecx<- CC 5922 SPILL(rIBASE) 5923 GET_VREG_WORD rIBASE %eax 1 # rIBASE<- v[BB+1] 5924 GET_VREG_R %ecx %ecx # ecx<- vCC 5925 GET_VREG_WORD %eax %eax 0 # eax<- v[BB+0] 5926 shrdl rIBASE,%eax 5927 shrl %cl,rIBASE 5928 testb $32,%cl 5929 je 2f 5930 movl rIBASE,%eax 5931 xorl rIBASE,rIBASE 59322: 5933 SET_VREG_WORD rIBASE rINST 1 # v[AA+1]<- rIBASE 5934 FETCH_INST_OPCODE 2 %ecx 5935 UNSPILL(rIBASE) 5936 SET_VREG_WORD %eax rINST 0 # v[BB+0]<- eax 5937 ADVANCE_PC 2 5938 GOTO_NEXT_R %ecx 5939 5940/* ------------------------------ */ 5941.L_OP_ADD_FLOAT: /* 0xa6 */ 5942/* File: x86/OP_ADD_FLOAT.S */ 5943/* File: x86/binflop.S */ 5944 /* 5945 * Generic 32-bit binary float operation. 5946 * 5947 * For: add-fp, sub-fp, mul-fp, div-fp 5948 */ 5949 /* binop vAA, vBB, vCC */ 5950 movzbl 2(rPC),%eax # eax<- CC 5951 movzbl 3(rPC),%ecx # ecx<- BB 5952 flds (rFP,%eax,4) # vCC to fp stack 5953 fadds (rFP,%ecx,4) # ex: faddp 5954 FETCH_INST_OPCODE 2 %ecx 5955 ADVANCE_PC 2 5956 fstps (rFP,rINST,4) # %st to vAA 5957 GOTO_NEXT_R %ecx 5958 5959 5960/* ------------------------------ */ 5961.L_OP_SUB_FLOAT: /* 0xa7 */ 5962/* File: x86/OP_SUB_FLOAT.S */ 5963/* File: x86/binflop.S */ 5964 /* 5965 * Generic 32-bit binary float operation. 5966 * 5967 * For: add-fp, sub-fp, mul-fp, div-fp 5968 */ 5969 /* binop vAA, vBB, vCC */ 5970 movzbl 2(rPC),%eax # eax<- CC 5971 movzbl 3(rPC),%ecx # ecx<- BB 5972 flds (rFP,%eax,4) # vCC to fp stack 5973 fsubs (rFP,%ecx,4) # ex: faddp 5974 FETCH_INST_OPCODE 2 %ecx 5975 ADVANCE_PC 2 5976 fstps (rFP,rINST,4) # %st to vAA 5977 GOTO_NEXT_R %ecx 5978 5979 5980/* ------------------------------ */ 5981.L_OP_MUL_FLOAT: /* 0xa8 */ 5982/* File: x86/OP_MUL_FLOAT.S */ 5983/* File: x86/binflop.S */ 5984 /* 5985 * Generic 32-bit binary float operation. 5986 * 5987 * For: add-fp, sub-fp, mul-fp, div-fp 5988 */ 5989 /* binop vAA, vBB, vCC */ 5990 movzbl 2(rPC),%eax # eax<- CC 5991 movzbl 3(rPC),%ecx # ecx<- BB 5992 flds (rFP,%eax,4) # vCC to fp stack 5993 fmuls (rFP,%ecx,4) # ex: faddp 5994 FETCH_INST_OPCODE 2 %ecx 5995 ADVANCE_PC 2 5996 fstps (rFP,rINST,4) # %st to vAA 5997 GOTO_NEXT_R %ecx 5998 5999 6000/* ------------------------------ */ 6001.L_OP_DIV_FLOAT: /* 0xa9 */ 6002/* File: x86/OP_DIV_FLOAT.S */ 6003/* File: x86/binflop.S */ 6004 /* 6005 * Generic 32-bit binary float operation. 6006 * 6007 * For: add-fp, sub-fp, mul-fp, div-fp 6008 */ 6009 /* binop vAA, vBB, vCC */ 6010 movzbl 2(rPC),%eax # eax<- CC 6011 movzbl 3(rPC),%ecx # ecx<- BB 6012 flds (rFP,%eax,4) # vCC to fp stack 6013 fdivs (rFP,%ecx,4) # ex: faddp 6014 FETCH_INST_OPCODE 2 %ecx 6015 ADVANCE_PC 2 6016 fstps (rFP,rINST,4) # %st to vAA 6017 GOTO_NEXT_R %ecx 6018 6019 6020/* ------------------------------ */ 6021.L_OP_REM_FLOAT: /* 0xaa */ 6022/* File: x86/OP_REM_FLOAT.S */ 6023 /* rem_float vAA, vBB, vCC */ 6024 movzbl 3(rPC),%ecx # ecx<- BB 6025 movzbl 2(rPC),%eax # eax<- CC 6026 flds (rFP,%ecx,4) # vCC to fp stack 6027 flds (rFP,%eax,4) # vCC to fp stack 6028 movzbl rINSTbl,%ecx # ecx<- AA 60291: 6030 fprem 6031 fstsw %ax 6032 sahf 6033 jp 1b 6034 fstp %st(1) 6035 FETCH_INST_OPCODE 2 %eax 6036 ADVANCE_PC 2 6037 fstps (rFP,%ecx,4) # %st to vAA 6038 GOTO_NEXT_R %eax 6039 6040/* ------------------------------ */ 6041.L_OP_ADD_DOUBLE: /* 0xab */ 6042/* File: x86/OP_ADD_DOUBLE.S */ 6043 /* 6044 * File: OP_ADD_DOUBLE.S 6045 */ 6046 6047 movzbl 2(rPC),%eax # eax<- BB 6048 movzbl 3(rPC),%ecx # ecx<- CC 6049 movq (rFP, %eax, 4), %xmm0 # %xmm0<- vBB 6050 movq (rFP, %ecx, 4), %xmm1 # %xmm1<- vCC 6051 FETCH_INST_OPCODE 2 %ecx 6052 addsd %xmm1, %xmm0 6053 ADVANCE_PC 2 6054 movq %xmm0, (rFP, rINST, 4) # vAA<- vBB * vCC 6055 GOTO_NEXT_R %ecx 6056 6057 6058/* ------------------------------ */ 6059.L_OP_SUB_DOUBLE: /* 0xac */ 6060/* File: x86/OP_SUB_DOUBLE.S */ 6061 /* 6062 * File: OP_SUB_DOUBLE.S 6063 */ 6064 6065 movzbl 2(rPC),%eax # eax<- BB 6066 movzbl 3(rPC),%ecx # ecx<- CC 6067 # TODO: movsd? 6068 movq (rFP, %eax, 4), %xmm0 # %xmm0<- vBB 6069 movq (rFP, %ecx, 4), %xmm1 # %xmm1<- vCC 6070 FETCH_INST_OPCODE 2 %ecx 6071 subsd %xmm1, %xmm0 6072 ADVANCE_PC 2 6073 movq %xmm0, (rFP, rINST, 4) # vAA<- vBB - vCC 6074 GOTO_NEXT_R %ecx 6075 6076/* ------------------------------ */ 6077.L_OP_MUL_DOUBLE: /* 0xad */ 6078/* File: x86/OP_MUL_DOUBLE.S */ 6079 /* 6080 * File: OP_MUL_DOUBLE.S 6081 */ 6082 6083 movzbl 2(rPC),%eax # eax<- BB 6084 movzbl 3(rPC),%ecx # ecx<- CC 6085 # TODO: movsd? 6086 movq (rFP, %eax, 4), %xmm0 # %xmm0<- vBB 6087 movq (rFP, %ecx, 4), %xmm1 # %xmm1<- vCC 6088 FETCH_INST_OPCODE 2 %ecx 6089 mulsd %xmm1, %xmm0 6090 ADVANCE_PC 2 6091 movq %xmm0, (rFP, rINST, 4) # vAA<- vBB * vCC 6092 GOTO_NEXT_R %ecx 6093 6094/* ------------------------------ */ 6095.L_OP_DIV_DOUBLE: /* 0xae */ 6096/* File: x86/OP_DIV_DOUBLE.S */ 6097/* File: x86/binflop.S */ 6098 /* 6099 * Generic 32-bit binary float operation. 6100 * 6101 * For: add-fp, sub-fp, mul-fp, div-fp 6102 */ 6103 /* binop vAA, vBB, vCC */ 6104 movzbl 2(rPC),%eax # eax<- CC 6105 movzbl 3(rPC),%ecx # ecx<- BB 6106 fldl (rFP,%eax,4) # vCC to fp stack 6107 fdivl (rFP,%ecx,4) # ex: faddp 6108 FETCH_INST_OPCODE 2 %ecx 6109 ADVANCE_PC 2 6110 fstpl (rFP,rINST,4) # %st to vAA 6111 GOTO_NEXT_R %ecx 6112 6113 6114/* ------------------------------ */ 6115.L_OP_REM_DOUBLE: /* 0xaf */ 6116/* File: x86/OP_REM_DOUBLE.S */ 6117 /* rem_float vAA, vBB, vCC */ 6118 movzbl 3(rPC),%ecx # ecx<- BB 6119 movzbl 2(rPC),%eax # eax<- CC 6120 fldl (rFP,%ecx,4) # vCC to fp stack 6121 fldl (rFP,%eax,4) # vCC to fp stack 6122 FETCH_INST_OPCODE 2 %ecx 61231: 6124 fprem 6125 fstsw %ax 6126 sahf 6127 jp 1b 6128 fstp %st(1) 6129 ADVANCE_PC 2 6130 fstpl (rFP,rINST,4) # %st to vAA 6131 GOTO_NEXT_R %ecx 6132 6133/* ------------------------------ */ 6134.L_OP_ADD_INT_2ADDR: /* 0xb0 */ 6135/* File: x86/OP_ADD_INT_2ADDR.S */ 6136/* File: x86/binop2addr.S */ 6137 /* 6138 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6139 * that specifies an instruction that performs "result = r0 op r1". 6140 * This could be an instruction or a function call. 6141 * 6142 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6143 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6144 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6145 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6146 */ 6147 /* binop/2addr vA, vB */ 6148 movzx rINSTbl,%ecx # ecx<- A+ 6149 sarl $4,rINST # rINST<- B 6150 GET_VREG_R %eax rINST # eax<- vB 6151 andb $0xf,%cl # ecx<- A 6152 addl %eax,(rFP,%ecx,4) # for ex: addl %eax,(rFP,%ecx,4) 6153 FETCH_INST_OPCODE 1 %ecx 6154 ADVANCE_PC 1 6155 GOTO_NEXT_R %ecx 6156 6157 6158/* ------------------------------ */ 6159.L_OP_SUB_INT_2ADDR: /* 0xb1 */ 6160/* File: x86/OP_SUB_INT_2ADDR.S */ 6161/* File: x86/binop2addr.S */ 6162 /* 6163 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6164 * that specifies an instruction that performs "result = r0 op r1". 6165 * This could be an instruction or a function call. 6166 * 6167 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6168 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6169 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6170 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6171 */ 6172 /* binop/2addr vA, vB */ 6173 movzx rINSTbl,%ecx # ecx<- A+ 6174 sarl $4,rINST # rINST<- B 6175 GET_VREG_R %eax rINST # eax<- vB 6176 andb $0xf,%cl # ecx<- A 6177 subl %eax,(rFP,%ecx,4) # for ex: addl %eax,(rFP,%ecx,4) 6178 FETCH_INST_OPCODE 1 %ecx 6179 ADVANCE_PC 1 6180 GOTO_NEXT_R %ecx 6181 6182 6183/* ------------------------------ */ 6184.L_OP_MUL_INT_2ADDR: /* 0xb2 */ 6185/* File: x86/OP_MUL_INT_2ADDR.S */ 6186 /* mul vA, vB */ 6187 movzx rINSTbl,%ecx # ecx<- A+ 6188 sarl $4,rINST # rINST<- B 6189 GET_VREG_R %eax rINST # eax<- vB 6190 andb $0xf,%cl # ecx<- A 6191 SPILL(rIBASE) 6192 imull (rFP,%ecx,4),%eax # trashes rIBASE/edx 6193 UNSPILL(rIBASE) 6194 SET_VREG %eax %ecx 6195 FETCH_INST_OPCODE 1 %ecx 6196 ADVANCE_PC 1 6197 GOTO_NEXT_R %ecx 6198 6199/* ------------------------------ */ 6200.L_OP_DIV_INT_2ADDR: /* 0xb3 */ 6201/* File: x86/OP_DIV_INT_2ADDR.S */ 6202/* File: x86/bindiv2addr.S */ 6203 /* 6204 * 32-bit binary div/rem operation. Handles special case of op0=minint and 6205 * op1=-1. 6206 */ 6207 /* div/rem/2addr vA, vB */ 6208 movzx rINSTbl,%ecx # eax<- BA 6209 SPILL(rIBASE) 6210 sarl $4,%ecx # ecx<- B 6211 GET_VREG_R %ecx %ecx # eax<- vBB 6212 andb $0xf,rINSTbl # rINST<- A 6213 GET_VREG_R %eax rINST # eax<- vBB 6214 cmpl $0,%ecx 6215 je common_errDivideByZero 6216 cmpl $-1,%ecx 6217 jne .LOP_DIV_INT_2ADDR_continue_div2addr 6218 cmpl $0x80000000,%eax 6219 jne .LOP_DIV_INT_2ADDR_continue_div2addr 6220 movl $0x80000000,%eax 6221 SET_VREG %eax rINST 6222 UNSPILL(rIBASE) 6223 FETCH_INST_OPCODE 1 %ecx 6224 ADVANCE_PC 1 6225 GOTO_NEXT_R %ecx 6226 6227.LOP_DIV_INT_2ADDR_continue_div2addr: 6228 cltd 6229 idivl %ecx 6230 SET_VREG %eax rINST 6231 UNSPILL(rIBASE) 6232 FETCH_INST_OPCODE 1 %ecx 6233 ADVANCE_PC 1 6234 GOTO_NEXT_R %ecx 6235 6236 6237/* ------------------------------ */ 6238.L_OP_REM_INT_2ADDR: /* 0xb4 */ 6239/* File: x86/OP_REM_INT_2ADDR.S */ 6240/* File: x86/bindiv2addr.S */ 6241 /* 6242 * 32-bit binary div/rem operation. Handles special case of op0=minint and 6243 * op1=-1. 6244 */ 6245 /* div/rem/2addr vA, vB */ 6246 movzx rINSTbl,%ecx # eax<- BA 6247 SPILL(rIBASE) 6248 sarl $4,%ecx # ecx<- B 6249 GET_VREG_R %ecx %ecx # eax<- vBB 6250 andb $0xf,rINSTbl # rINST<- A 6251 GET_VREG_R %eax rINST # eax<- vBB 6252 cmpl $0,%ecx 6253 je common_errDivideByZero 6254 cmpl $-1,%ecx 6255 jne .LOP_REM_INT_2ADDR_continue_div2addr 6256 cmpl $0x80000000,%eax 6257 jne .LOP_REM_INT_2ADDR_continue_div2addr 6258 movl $0,rIBASE 6259 SET_VREG rIBASE rINST 6260 UNSPILL(rIBASE) 6261 FETCH_INST_OPCODE 1 %ecx 6262 ADVANCE_PC 1 6263 GOTO_NEXT_R %ecx 6264 6265.LOP_REM_INT_2ADDR_continue_div2addr: 6266 cltd 6267 idivl %ecx 6268 SET_VREG rIBASE rINST 6269 UNSPILL(rIBASE) 6270 FETCH_INST_OPCODE 1 %ecx 6271 ADVANCE_PC 1 6272 GOTO_NEXT_R %ecx 6273 6274 6275/* ------------------------------ */ 6276.L_OP_AND_INT_2ADDR: /* 0xb5 */ 6277/* File: x86/OP_AND_INT_2ADDR.S */ 6278/* File: x86/binop2addr.S */ 6279 /* 6280 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6281 * that specifies an instruction that performs "result = r0 op r1". 6282 * This could be an instruction or a function call. 6283 * 6284 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6285 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6286 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6287 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6288 */ 6289 /* binop/2addr vA, vB */ 6290 movzx rINSTbl,%ecx # ecx<- A+ 6291 sarl $4,rINST # rINST<- B 6292 GET_VREG_R %eax rINST # eax<- vB 6293 andb $0xf,%cl # ecx<- A 6294 andl %eax,(rFP,%ecx,4) # for ex: addl %eax,(rFP,%ecx,4) 6295 FETCH_INST_OPCODE 1 %ecx 6296 ADVANCE_PC 1 6297 GOTO_NEXT_R %ecx 6298 6299 6300/* ------------------------------ */ 6301.L_OP_OR_INT_2ADDR: /* 0xb6 */ 6302/* File: x86/OP_OR_INT_2ADDR.S */ 6303/* File: x86/binop2addr.S */ 6304 /* 6305 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6306 * that specifies an instruction that performs "result = r0 op r1". 6307 * This could be an instruction or a function call. 6308 * 6309 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6310 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6311 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6312 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6313 */ 6314 /* binop/2addr vA, vB */ 6315 movzx rINSTbl,%ecx # ecx<- A+ 6316 sarl $4,rINST # rINST<- B 6317 GET_VREG_R %eax rINST # eax<- vB 6318 andb $0xf,%cl # ecx<- A 6319 orl %eax,(rFP,%ecx,4) # for ex: addl %eax,(rFP,%ecx,4) 6320 FETCH_INST_OPCODE 1 %ecx 6321 ADVANCE_PC 1 6322 GOTO_NEXT_R %ecx 6323 6324 6325/* ------------------------------ */ 6326.L_OP_XOR_INT_2ADDR: /* 0xb7 */ 6327/* File: x86/OP_XOR_INT_2ADDR.S */ 6328/* File: x86/binop2addr.S */ 6329 /* 6330 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6331 * that specifies an instruction that performs "result = r0 op r1". 6332 * This could be an instruction or a function call. 6333 * 6334 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6335 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6336 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6337 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6338 */ 6339 /* binop/2addr vA, vB */ 6340 movzx rINSTbl,%ecx # ecx<- A+ 6341 sarl $4,rINST # rINST<- B 6342 GET_VREG_R %eax rINST # eax<- vB 6343 andb $0xf,%cl # ecx<- A 6344 xorl %eax,(rFP,%ecx,4) # for ex: addl %eax,(rFP,%ecx,4) 6345 FETCH_INST_OPCODE 1 %ecx 6346 ADVANCE_PC 1 6347 GOTO_NEXT_R %ecx 6348 6349 6350/* ------------------------------ */ 6351.L_OP_SHL_INT_2ADDR: /* 0xb8 */ 6352/* File: x86/OP_SHL_INT_2ADDR.S */ 6353/* File: x86/shop2addr.S */ 6354 /* 6355 * Generic 32-bit "shift/2addr" operation. 6356 */ 6357 /* shift/2addr vA, vB */ 6358 movzx rINSTbl,%ecx # eax<- BA 6359 sarl $4,%ecx # ecx<- B 6360 GET_VREG_R %ecx %ecx # eax<- vBB 6361 andb $0xf,rINSTbl # rINST<- A 6362 GET_VREG_R %eax rINST # eax<- vAA 6363 sall %cl,%eax # ex: sarl %cl,%eax 6364 FETCH_INST_OPCODE 1 %ecx 6365 SET_VREG %eax rINST 6366 ADVANCE_PC 1 6367 GOTO_NEXT_R %ecx 6368 6369 6370/* ------------------------------ */ 6371.L_OP_SHR_INT_2ADDR: /* 0xb9 */ 6372/* File: x86/OP_SHR_INT_2ADDR.S */ 6373/* File: x86/shop2addr.S */ 6374 /* 6375 * Generic 32-bit "shift/2addr" operation. 6376 */ 6377 /* shift/2addr vA, vB */ 6378 movzx rINSTbl,%ecx # eax<- BA 6379 sarl $4,%ecx # ecx<- B 6380 GET_VREG_R %ecx %ecx # eax<- vBB 6381 andb $0xf,rINSTbl # rINST<- A 6382 GET_VREG_R %eax rINST # eax<- vAA 6383 sarl %cl,%eax # ex: sarl %cl,%eax 6384 FETCH_INST_OPCODE 1 %ecx 6385 SET_VREG %eax rINST 6386 ADVANCE_PC 1 6387 GOTO_NEXT_R %ecx 6388 6389 6390/* ------------------------------ */ 6391.L_OP_USHR_INT_2ADDR: /* 0xba */ 6392/* File: x86/OP_USHR_INT_2ADDR.S */ 6393/* File: x86/shop2addr.S */ 6394 /* 6395 * Generic 32-bit "shift/2addr" operation. 6396 */ 6397 /* shift/2addr vA, vB */ 6398 movzx rINSTbl,%ecx # eax<- BA 6399 sarl $4,%ecx # ecx<- B 6400 GET_VREG_R %ecx %ecx # eax<- vBB 6401 andb $0xf,rINSTbl # rINST<- A 6402 GET_VREG_R %eax rINST # eax<- vAA 6403 shrl %cl,%eax # ex: sarl %cl,%eax 6404 FETCH_INST_OPCODE 1 %ecx 6405 SET_VREG %eax rINST 6406 ADVANCE_PC 1 6407 GOTO_NEXT_R %ecx 6408 6409 6410/* ------------------------------ */ 6411.L_OP_ADD_LONG_2ADDR: /* 0xbb */ 6412/* File: x86/OP_ADD_LONG_2ADDR.S */ 6413/* File: x86/binopWide2addr.S */ 6414 /* 6415 * Generic 64-bit binary operation. 6416 */ 6417 /* binop/2addr vA, vB */ 6418 movzbl rINSTbl,%ecx # ecx<- BA 6419 sarl $4,%ecx # ecx<- B 6420 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 6421 GET_VREG_WORD %ecx %ecx 1 # eax<- v[B+1] 6422 andb $0xF,rINSTbl # rINST<- A 6423 addl %eax,(rFP,rINST,4) # example: addl %eax,(rFP,rINST,4) 6424 adcl %ecx,4(rFP,rINST,4) # example: adcl %ecx,4(rFP,rINST,4) 6425 FETCH_INST_OPCODE 1 %ecx 6426 ADVANCE_PC 1 6427 GOTO_NEXT_R %ecx 6428 6429 6430/* ------------------------------ */ 6431.L_OP_SUB_LONG_2ADDR: /* 0xbc */ 6432/* File: x86/OP_SUB_LONG_2ADDR.S */ 6433/* File: x86/binopWide2addr.S */ 6434 /* 6435 * Generic 64-bit binary operation. 6436 */ 6437 /* binop/2addr vA, vB */ 6438 movzbl rINSTbl,%ecx # ecx<- BA 6439 sarl $4,%ecx # ecx<- B 6440 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 6441 GET_VREG_WORD %ecx %ecx 1 # eax<- v[B+1] 6442 andb $0xF,rINSTbl # rINST<- A 6443 subl %eax,(rFP,rINST,4) # example: addl %eax,(rFP,rINST,4) 6444 sbbl %ecx,4(rFP,rINST,4) # example: adcl %ecx,4(rFP,rINST,4) 6445 FETCH_INST_OPCODE 1 %ecx 6446 ADVANCE_PC 1 6447 GOTO_NEXT_R %ecx 6448 6449 6450/* ------------------------------ */ 6451.L_OP_MUL_LONG_2ADDR: /* 0xbd */ 6452/* File: x86/OP_MUL_LONG_2ADDR.S */ 6453 /* 6454 * Signed 64-bit integer multiply, 2-addr version 6455 * 6456 * We could definately use more free registers for 6457 * this code. We must spill %edx (rIBASE) because it 6458 * is used by imul. We'll also spill rINST (ebx), 6459 * giving us eax, ebc, ecx and rIBASE as computational 6460 * temps. On top of that, we'll spill %esi (edi) 6461 * for use as the vA pointer and rFP (esi) for use 6462 * as the vB pointer. Yuck. 6463 */ 6464 /* mul-long/2addr vA, vB */ 6465 movzbl rINSTbl,%eax # eax<- BA 6466 andb $0xf,%al # eax<- A 6467 sarl $4,rINST # rINST<- B 6468 SPILL_TMP2(%esi) 6469 SPILL(rFP) 6470 SPILL(rIBASE) 6471 leal (rFP,%eax,4),%esi # %esi<- &v[A] 6472 leal (rFP,rINST,4),rFP # rFP<- &v[B] 6473 movl 4(%esi),%ecx # ecx<- Amsw 6474 imull (rFP),%ecx # ecx<- (Amsw*Blsw) 6475 movl 4(rFP),%eax # eax<- Bmsw 6476 imull (%esi),%eax # eax<- (Bmsw*Alsw) 6477 addl %eax,%ecx # ecx<- (Amsw*Blsw)+(Bmsw*Alsw) 6478 movl (rFP),%eax # eax<- Blsw 6479 mull (%esi) # eax<- (Blsw*Alsw) 6480 leal (%ecx,rIBASE),rIBASE # full result now in %edx:%eax 6481 movl rIBASE,4(%esi) # v[A+1]<- rIBASE 6482 movl %eax,(%esi) # v[A]<- %eax 6483 UNSPILL_TMP2(%esi) 6484 FETCH_INST_OPCODE 1 %ecx 6485 UNSPILL(rIBASE) 6486 UNSPILL(rFP) 6487 ADVANCE_PC 1 6488 GOTO_NEXT_R %ecx 6489 6490/* ------------------------------ */ 6491.L_OP_DIV_LONG_2ADDR: /* 0xbe */ 6492/* File: x86/OP_DIV_LONG_2ADDR.S */ 6493 /* div/2addr vA, vB */ 6494 movzbl rINSTbl,%eax 6495 shrl $4,%eax # eax<- B 6496 andb $0xf,rINSTbl # rINST<- A 6497 SPILL(rIBASE) # save rIBASE/%edx 6498 GET_VREG_WORD rIBASE %eax 0 6499 GET_VREG_WORD %eax %eax 1 6500 movl rIBASE,OUT_ARG2(%esp) 6501 testl %eax,%eax 6502 je .LOP_DIV_LONG_2ADDR_check_zero 6503 cmpl $-1,%eax 6504 je .LOP_DIV_LONG_2ADDR_check_neg1 6505.LOP_DIV_LONG_2ADDR_notSpecial: 6506 GET_VREG_WORD rIBASE rINST 0 6507 GET_VREG_WORD %ecx rINST 1 6508.LOP_DIV_LONG_2ADDR_notSpecial1: 6509 movl %eax,OUT_ARG3(%esp) 6510 movl rIBASE,OUT_ARG0(%esp) 6511 movl %ecx,OUT_ARG1(%esp) 6512 call __divdi3 6513.LOP_DIV_LONG_2ADDR_finish: 6514 SET_VREG_WORD rIBASE rINST 1 6515 UNSPILL(rIBASE) # restore rIBASE/%edx 6516 SET_VREG_WORD %eax rINST 0 6517 FETCH_INST_OPCODE 1 %ecx 6518 ADVANCE_PC 1 6519 GOTO_NEXT_R %ecx 6520 6521.LOP_DIV_LONG_2ADDR_check_zero: 6522 testl rIBASE,rIBASE 6523 jne .LOP_DIV_LONG_2ADDR_notSpecial 6524 jmp common_errDivideByZero 6525.LOP_DIV_LONG_2ADDR_check_neg1: 6526 testl rIBASE,%eax 6527 jne .LOP_DIV_LONG_2ADDR_notSpecial 6528 GET_VREG_WORD rIBASE rINST 0 6529 GET_VREG_WORD %ecx rINST 1 6530 testl rIBASE,rIBASE 6531 jne .LOP_DIV_LONG_2ADDR_notSpecial1 6532 cmpl $0x80000000,%ecx 6533 jne .LOP_DIV_LONG_2ADDR_notSpecial1 6534 /* minint / -1, return minint on div, 0 on rem */ 6535 xorl %eax,%eax 6536 movl $0x80000000,rIBASE 6537 jmp .LOP_DIV_LONG_2ADDR_finish 6538 6539/* ------------------------------ */ 6540.L_OP_REM_LONG_2ADDR: /* 0xbf */ 6541/* File: x86/OP_REM_LONG_2ADDR.S */ 6542/* File: x86/OP_DIV_LONG_2ADDR.S */ 6543 /* div/2addr vA, vB */ 6544 movzbl rINSTbl,%eax 6545 shrl $4,%eax # eax<- B 6546 andb $0xf,rINSTbl # rINST<- A 6547 SPILL(rIBASE) # save rIBASE/%edx 6548 GET_VREG_WORD rIBASE %eax 0 6549 GET_VREG_WORD %eax %eax 1 6550 movl rIBASE,OUT_ARG2(%esp) 6551 testl %eax,%eax 6552 je .LOP_REM_LONG_2ADDR_check_zero 6553 cmpl $-1,%eax 6554 je .LOP_REM_LONG_2ADDR_check_neg1 6555.LOP_REM_LONG_2ADDR_notSpecial: 6556 GET_VREG_WORD rIBASE rINST 0 6557 GET_VREG_WORD %ecx rINST 1 6558.LOP_REM_LONG_2ADDR_notSpecial1: 6559 movl %eax,OUT_ARG3(%esp) 6560 movl rIBASE,OUT_ARG0(%esp) 6561 movl %ecx,OUT_ARG1(%esp) 6562 call __moddi3 6563.LOP_REM_LONG_2ADDR_finish: 6564 SET_VREG_WORD rIBASE rINST 1 6565 UNSPILL(rIBASE) # restore rIBASE/%edx 6566 SET_VREG_WORD %eax rINST 0 6567 FETCH_INST_OPCODE 1 %ecx 6568 ADVANCE_PC 1 6569 GOTO_NEXT_R %ecx 6570 6571.LOP_REM_LONG_2ADDR_check_zero: 6572 testl rIBASE,rIBASE 6573 jne .LOP_REM_LONG_2ADDR_notSpecial 6574 jmp common_errDivideByZero 6575.LOP_REM_LONG_2ADDR_check_neg1: 6576 testl rIBASE,%eax 6577 jne .LOP_REM_LONG_2ADDR_notSpecial 6578 GET_VREG_WORD rIBASE rINST 0 6579 GET_VREG_WORD %ecx rINST 1 6580 testl rIBASE,rIBASE 6581 jne .LOP_REM_LONG_2ADDR_notSpecial1 6582 cmpl $0x80000000,%ecx 6583 jne .LOP_REM_LONG_2ADDR_notSpecial1 6584 /* minint / -1, return minint on div, 0 on rem */ 6585 xorl %eax,%eax 6586 movl $0,rIBASE 6587 jmp .LOP_REM_LONG_2ADDR_finish 6588 6589 6590/* ------------------------------ */ 6591.L_OP_AND_LONG_2ADDR: /* 0xc0 */ 6592/* File: x86/OP_AND_LONG_2ADDR.S */ 6593/* File: x86/binopWide2addr.S */ 6594 /* 6595 * Generic 64-bit binary operation. 6596 */ 6597 /* binop/2addr vA, vB */ 6598 movzbl rINSTbl,%ecx # ecx<- BA 6599 sarl $4,%ecx # ecx<- B 6600 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 6601 GET_VREG_WORD %ecx %ecx 1 # eax<- v[B+1] 6602 andb $0xF,rINSTbl # rINST<- A 6603 andl %eax,(rFP,rINST,4) # example: addl %eax,(rFP,rINST,4) 6604 andl %ecx,4(rFP,rINST,4) # example: adcl %ecx,4(rFP,rINST,4) 6605 FETCH_INST_OPCODE 1 %ecx 6606 ADVANCE_PC 1 6607 GOTO_NEXT_R %ecx 6608 6609 6610/* ------------------------------ */ 6611.L_OP_OR_LONG_2ADDR: /* 0xc1 */ 6612/* File: x86/OP_OR_LONG_2ADDR.S */ 6613/* File: x86/binopWide2addr.S */ 6614 /* 6615 * Generic 64-bit binary operation. 6616 */ 6617 /* binop/2addr vA, vB */ 6618 movzbl rINSTbl,%ecx # ecx<- BA 6619 sarl $4,%ecx # ecx<- B 6620 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 6621 GET_VREG_WORD %ecx %ecx 1 # eax<- v[B+1] 6622 andb $0xF,rINSTbl # rINST<- A 6623 orl %eax,(rFP,rINST,4) # example: addl %eax,(rFP,rINST,4) 6624 orl %ecx,4(rFP,rINST,4) # example: adcl %ecx,4(rFP,rINST,4) 6625 FETCH_INST_OPCODE 1 %ecx 6626 ADVANCE_PC 1 6627 GOTO_NEXT_R %ecx 6628 6629 6630/* ------------------------------ */ 6631.L_OP_XOR_LONG_2ADDR: /* 0xc2 */ 6632/* File: x86/OP_XOR_LONG_2ADDR.S */ 6633/* File: x86/binopWide2addr.S */ 6634 /* 6635 * Generic 64-bit binary operation. 6636 */ 6637 /* binop/2addr vA, vB */ 6638 movzbl rINSTbl,%ecx # ecx<- BA 6639 sarl $4,%ecx # ecx<- B 6640 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 6641 GET_VREG_WORD %ecx %ecx 1 # eax<- v[B+1] 6642 andb $0xF,rINSTbl # rINST<- A 6643 xorl %eax,(rFP,rINST,4) # example: addl %eax,(rFP,rINST,4) 6644 xorl %ecx,4(rFP,rINST,4) # example: adcl %ecx,4(rFP,rINST,4) 6645 FETCH_INST_OPCODE 1 %ecx 6646 ADVANCE_PC 1 6647 GOTO_NEXT_R %ecx 6648 6649 6650/* ------------------------------ */ 6651.L_OP_SHL_LONG_2ADDR: /* 0xc3 */ 6652/* File: x86/OP_SHL_LONG_2ADDR.S */ 6653 /* 6654 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 6655 * 32-bit shift distance. 6656 */ 6657 /* shl-long/2addr vA, vB */ 6658 /* ecx gets shift count */ 6659 /* Need to spill rIBASE */ 6660 /* rINSTw gets AA */ 6661 movzbl rINSTbl,%ecx # ecx<- BA 6662 andb $0xf,rINSTbl # rINST<- A 6663 GET_VREG_WORD %eax rINST 0 # eax<- v[AA+0] 6664 sarl $4,%ecx # ecx<- B 6665 SPILL(rIBASE) 6666 GET_VREG_WORD rIBASE rINST 1 # rIBASE<- v[AA+1] 6667 GET_VREG_R %ecx %ecx # ecx<- vBB 6668 shldl %eax,rIBASE 6669 sall %cl,%eax 6670 testb $32,%cl 6671 je 2f 6672 movl %eax,rIBASE 6673 xorl %eax,%eax 66742: 6675 SET_VREG_WORD rIBASE rINST 1 # v[AA+1]<- rIBASE 6676 UNSPILL(rIBASE) 6677 FETCH_INST_OPCODE 1 %ecx 6678 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- eax 6679 ADVANCE_PC 1 6680 GOTO_NEXT_R %ecx 6681 6682/* ------------------------------ */ 6683.L_OP_SHR_LONG_2ADDR: /* 0xc4 */ 6684/* File: x86/OP_SHR_LONG_2ADDR.S */ 6685 /* 6686 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 6687 * 32-bit shift distance. 6688 */ 6689 /* shl-long/2addr vA, vB */ 6690 /* ecx gets shift count */ 6691 /* Need to spill rIBASE */ 6692 /* rINSTw gets AA */ 6693 movzbl rINSTbl,%ecx # ecx<- BA 6694 andb $0xf,rINSTbl # rINST<- A 6695 GET_VREG_WORD %eax rINST 0 # eax<- v[AA+0] 6696 sarl $4,%ecx # ecx<- B 6697 SPILL(rIBASE) 6698 GET_VREG_WORD rIBASE rINST 1 # rIBASE<- v[AA+1] 6699 GET_VREG_R %ecx %ecx # ecx<- vBB 6700 shrdl rIBASE,%eax 6701 sarl %cl,rIBASE 6702 testb $32,%cl 6703 je 2f 6704 movl rIBASE,%eax 6705 sarl $31,rIBASE 67062: 6707 SET_VREG_WORD rIBASE rINST 1 # v[AA+1]<- rIBASE 6708 UNSPILL(rIBASE) 6709 FETCH_INST_OPCODE 1 %ecx 6710 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- eax 6711 ADVANCE_PC 1 6712 GOTO_NEXT_R %ecx 6713 6714/* ------------------------------ */ 6715.L_OP_USHR_LONG_2ADDR: /* 0xc5 */ 6716/* File: x86/OP_USHR_LONG_2ADDR.S */ 6717 /* 6718 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 6719 * 32-bit shift distance. 6720 */ 6721 /* shl-long/2addr vA, vB */ 6722 /* ecx gets shift count */ 6723 /* Need to spill rIBASE */ 6724 /* rINSTw gets AA */ 6725 movzbl rINSTbl,%ecx # ecx<- BA 6726 andb $0xf,rINSTbl # rINST<- A 6727 GET_VREG_WORD %eax rINST 0 # eax<- v[AA+0] 6728 sarl $4,%ecx # ecx<- B 6729 SPILL(rIBASE) 6730 GET_VREG_WORD rIBASE rINST 1 # rIBASE<- v[AA+1] 6731 GET_VREG_R %ecx %ecx # ecx<- vBB 6732 shrdl rIBASE,%eax 6733 shrl %cl,rIBASE 6734 testb $32,%cl 6735 je 2f 6736 movl rIBASE,%eax 6737 xorl rIBASE,rIBASE 67382: 6739 SET_VREG_WORD rIBASE rINST 1 # v[AA+1]<- rIBASE 6740 FETCH_INST_OPCODE 1 %ecx 6741 UNSPILL(rIBASE) 6742 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- eax 6743 ADVANCE_PC 1 6744 GOTO_NEXT_R %ecx 6745 6746/* ------------------------------ */ 6747.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 6748/* File: x86/OP_ADD_FLOAT_2ADDR.S */ 6749/* File: x86/binflop2addr.S */ 6750 /* 6751 * Generic 32-bit binary float operation. 6752 * 6753 * For: add-fp, sub-fp, mul-fp, div-fp 6754 */ 6755 6756 /* binop/2addr vA, vB */ 6757 movzx rINSTbl,%ecx # ecx<- A+ 6758 andb $0xf,%cl # ecx<- A 6759 flds (rFP,%ecx,4) # vAA to fp stack 6760 sarl $4,rINST # rINST<- B 6761 fadds (rFP,rINST,4) # ex: faddp 6762 FETCH_INST_OPCODE 1 %eax 6763 ADVANCE_PC 1 6764 fstps (rFP,%ecx,4) # %st to vA 6765 GOTO_NEXT_R %eax 6766 6767 6768/* ------------------------------ */ 6769.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 6770/* File: x86/OP_SUB_FLOAT_2ADDR.S */ 6771/* File: x86/binflop2addr.S */ 6772 /* 6773 * Generic 32-bit binary float operation. 6774 * 6775 * For: add-fp, sub-fp, mul-fp, div-fp 6776 */ 6777 6778 /* binop/2addr vA, vB */ 6779 movzx rINSTbl,%ecx # ecx<- A+ 6780 andb $0xf,%cl # ecx<- A 6781 flds (rFP,%ecx,4) # vAA to fp stack 6782 sarl $4,rINST # rINST<- B 6783 fsubs (rFP,rINST,4) # ex: faddp 6784 FETCH_INST_OPCODE 1 %eax 6785 ADVANCE_PC 1 6786 fstps (rFP,%ecx,4) # %st to vA 6787 GOTO_NEXT_R %eax 6788 6789 6790/* ------------------------------ */ 6791.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 6792/* File: x86/OP_MUL_FLOAT_2ADDR.S */ 6793/* File: x86/binflop2addr.S */ 6794 /* 6795 * Generic 32-bit binary float operation. 6796 * 6797 * For: add-fp, sub-fp, mul-fp, div-fp 6798 */ 6799 6800 /* binop/2addr vA, vB */ 6801 movzx rINSTbl,%ecx # ecx<- A+ 6802 andb $0xf,%cl # ecx<- A 6803 flds (rFP,%ecx,4) # vAA to fp stack 6804 sarl $4,rINST # rINST<- B 6805 fmuls (rFP,rINST,4) # ex: faddp 6806 FETCH_INST_OPCODE 1 %eax 6807 ADVANCE_PC 1 6808 fstps (rFP,%ecx,4) # %st to vA 6809 GOTO_NEXT_R %eax 6810 6811 6812/* ------------------------------ */ 6813.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 6814/* File: x86/OP_DIV_FLOAT_2ADDR.S */ 6815/* File: x86/binflop2addr.S */ 6816 /* 6817 * Generic 32-bit binary float operation. 6818 * 6819 * For: add-fp, sub-fp, mul-fp, div-fp 6820 */ 6821 6822 /* binop/2addr vA, vB */ 6823 movzx rINSTbl,%ecx # ecx<- A+ 6824 andb $0xf,%cl # ecx<- A 6825 flds (rFP,%ecx,4) # vAA to fp stack 6826 sarl $4,rINST # rINST<- B 6827 fdivs (rFP,rINST,4) # ex: faddp 6828 FETCH_INST_OPCODE 1 %eax 6829 ADVANCE_PC 1 6830 fstps (rFP,%ecx,4) # %st to vA 6831 GOTO_NEXT_R %eax 6832 6833 6834/* ------------------------------ */ 6835.L_OP_REM_FLOAT_2ADDR: /* 0xca */ 6836/* File: x86/OP_REM_FLOAT_2ADDR.S */ 6837 /* rem_float/2addr vA, vB */ 6838 movzx rINSTbl,%ecx # ecx<- A+ 6839 sarl $4,rINST # rINST<- B 6840 flds (rFP,rINST,4) # vBB to fp stack 6841 andb $0xf,%cl # ecx<- A 6842 flds (rFP,%ecx,4) # vAA to fp stack 68431: 6844 fprem 6845 fstsw %ax 6846 sahf 6847 jp 1b 6848 fstp %st(1) 6849 FETCH_INST_OPCODE 1 %eax 6850 ADVANCE_PC 1 6851 fstps (rFP,%ecx,4) # %st to vA 6852 GOTO_NEXT_R %eax 6853 6854/* ------------------------------ */ 6855.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 6856/* File: x86/OP_ADD_DOUBLE_2ADDR.S */ 6857 /* 6858 * File: OP_ADD_DOUBLE_2ADDR.S 6859 */ 6860 6861 movzx rINSTbl,%ecx # ecx<- A+ 6862 andb $0xf,%cl # ecx<- A 6863 sarl $4,rINST # rINST<- B 6864 movq (rFP, rINST, 4), %xmm1 # %xmm1<- vB 6865 movq (rFP, %ecx, 4), %xmm0 # %xmm0<- vA 6866 FETCH_INST_OPCODE 1 %eax 6867 addsd %xmm1, %xmm0 # %xmm0<- vA op vB 6868 ADVANCE_PC 1 6869 movq %xmm0, (rFP, %ecx, 4) # vA<- %xmm0; result 6870 GOTO_NEXT_R %eax 6871 6872/* ------------------------------ */ 6873.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 6874/* File: x86/OP_SUB_DOUBLE_2ADDR.S */ 6875 /* 6876 * File: OP_SUB_DOUBLE_2ADDR.S 6877 */ 6878 6879 movzx rINSTbl,%ecx # ecx<- A+ 6880 andb $0xf,%cl # ecx<- A 6881 sarl $4,rINST # rINST<- B 6882 # TODO: movsd? 6883 movq (rFP, rINST, 4), %xmm1 # %xmm1<- vB 6884 movq (rFP, %ecx, 4), %xmm0 # %xmm0<- vA 6885 FETCH_INST_OPCODE 1 %eax 6886 subsd %xmm1, %xmm0 # %xmm0<- vA op vB 6887 ADVANCE_PC 1 6888 movq %xmm0, (rFP, %ecx, 4) # vA<- %xmm0; result 6889 GOTO_NEXT_R %eax 6890 6891/* ------------------------------ */ 6892.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 6893/* File: x86/OP_MUL_DOUBLE_2ADDR.S */ 6894 /* 6895 * File: OP_MUL_DOUBLE_2ADDR.S 6896 */ 6897 6898 movzx rINSTbl,%ecx # ecx<- A+ 6899 andb $0xf,%cl # ecx<- A 6900 sarl $4,rINST # rINST<- B 6901 # TODO: movsd? 6902 movq (rFP, rINST, 4), %xmm1 # %xmm1<- vB 6903 movq (rFP, %ecx, 4), %xmm0 # %xmm0<- vA 6904 FETCH_INST_OPCODE 1 %eax 6905 mulsd %xmm1, %xmm0 # %xmm0<- vA op vB 6906 ADVANCE_PC 1 6907 movq %xmm0, (rFP, %ecx, 4) # vA<- %xmm0; result 6908 GOTO_NEXT_R %eax 6909 6910/* ------------------------------ */ 6911.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 6912/* File: x86/OP_DIV_DOUBLE_2ADDR.S */ 6913/* File: x86/binflop2addr.S */ 6914 /* 6915 * Generic 32-bit binary float operation. 6916 * 6917 * For: add-fp, sub-fp, mul-fp, div-fp 6918 */ 6919 6920 /* binop/2addr vA, vB */ 6921 movzx rINSTbl,%ecx # ecx<- A+ 6922 andb $0xf,%cl # ecx<- A 6923 fldl (rFP,%ecx,4) # vAA to fp stack 6924 sarl $4,rINST # rINST<- B 6925 fdivl (rFP,rINST,4) # ex: faddp 6926 FETCH_INST_OPCODE 1 %eax 6927 ADVANCE_PC 1 6928 fstpl (rFP,%ecx,4) # %st to vA 6929 GOTO_NEXT_R %eax 6930 6931 6932/* ------------------------------ */ 6933.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 6934/* File: x86/OP_REM_DOUBLE_2ADDR.S */ 6935 /* rem_float/2addr vA, vB */ 6936 movzx rINSTbl,%ecx # ecx<- A+ 6937 sarl $4,rINST # rINST<- B 6938 fldl (rFP,rINST,4) # vBB to fp stack 6939 andb $0xf,%cl # ecx<- A 6940 fldl (rFP,%ecx,4) # vAA to fp stack 69411: 6942 fprem 6943 fstsw %ax 6944 sahf 6945 jp 1b 6946 fstp %st(1) 6947 FETCH_INST_OPCODE 1 %eax 6948 ADVANCE_PC 1 6949 fstpl (rFP,%ecx,4) # %st to vA 6950 GOTO_NEXT_R %eax 6951 6952/* ------------------------------ */ 6953.L_OP_ADD_INT_LIT16: /* 0xd0 */ 6954/* File: x86/OP_ADD_INT_LIT16.S */ 6955/* File: x86/binopLit16.S */ 6956 /* 6957 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6958 * that specifies an instruction that performs "result = eax op ecx". 6959 * This could be an x86 instruction or a function call. (If the result 6960 * comes back in a register other than eax, you can override "result".) 6961 * 6962 * For: add-int/lit16, rsub-int, 6963 * and-int/lit16, or-int/lit16, xor-int/lit16 6964 */ 6965 /* binop/lit16 vA, vB, #+CCCC */ 6966 movzbl rINSTbl,%eax # eax<- 000000BA 6967 sarl $4,%eax # eax<- B 6968 GET_VREG_R %eax %eax # eax<- vB 6969 movswl 2(rPC),%ecx # ecx<- ssssCCCC 6970 andb $0xf,rINSTbl # rINST<- A 6971 addl %ecx,%eax # for example: addl %ecx, %eax 6972 SET_VREG %eax rINST 6973 FETCH_INST_OPCODE 2 %ecx 6974 ADVANCE_PC 2 6975 GOTO_NEXT_R %ecx 6976 6977 6978/* ------------------------------ */ 6979.L_OP_RSUB_INT: /* 0xd1 */ 6980/* File: x86/OP_RSUB_INT.S */ 6981/* File: x86/binopLit16.S */ 6982 /* 6983 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6984 * that specifies an instruction that performs "result = eax op ecx". 6985 * This could be an x86 instruction or a function call. (If the result 6986 * comes back in a register other than eax, you can override "result".) 6987 * 6988 * For: add-int/lit16, rsub-int, 6989 * and-int/lit16, or-int/lit16, xor-int/lit16 6990 */ 6991 /* binop/lit16 vA, vB, #+CCCC */ 6992 movzbl rINSTbl,%eax # eax<- 000000BA 6993 sarl $4,%eax # eax<- B 6994 GET_VREG_R %eax %eax # eax<- vB 6995 movswl 2(rPC),%ecx # ecx<- ssssCCCC 6996 andb $0xf,rINSTbl # rINST<- A 6997 subl %eax,%ecx # for example: addl %ecx, %eax 6998 SET_VREG %ecx rINST 6999 FETCH_INST_OPCODE 2 %ecx 7000 ADVANCE_PC 2 7001 GOTO_NEXT_R %ecx 7002 7003 7004/* ------------------------------ */ 7005.L_OP_MUL_INT_LIT16: /* 0xd2 */ 7006/* File: x86/OP_MUL_INT_LIT16.S */ 7007 /* mul/lit16 vA, vB, #+CCCC */ 7008 /* Need A in rINST, ssssCCCC in ecx, vB in eax */ 7009 movzbl rINSTbl,%eax # eax<- 000000BA 7010 sarl $4,%eax # eax<- B 7011 GET_VREG_R %eax %eax # eax<- vB 7012 movswl 2(rPC),%ecx # ecx<- ssssCCCC 7013 andb $0xf,rINSTbl # rINST<- A 7014 SPILL(rIBASE) 7015 imull %ecx,%eax # trashes rIBASE/edx 7016 UNSPILL(rIBASE) 7017 FETCH_INST_OPCODE 2 %ecx 7018 ADVANCE_PC 2 7019 SET_VREG %eax rINST 7020 GOTO_NEXT_R %ecx 7021 7022/* ------------------------------ */ 7023.L_OP_DIV_INT_LIT16: /* 0xd3 */ 7024/* File: x86/OP_DIV_INT_LIT16.S */ 7025/* File: x86/bindivLit16.S */ 7026 /* 7027 * 32-bit binary div/rem operation. Handles special case of op0=minint and 7028 * op1=-1. 7029 */ 7030 /* div/rem/lit16 vA, vB, #+CCCC */ 7031 /* Need A in rINST, ssssCCCC in ecx, vB in eax */ 7032 movzbl rINSTbl,%eax # eax<- 000000BA 7033 SPILL(rIBASE) 7034 sarl $4,%eax # eax<- B 7035 GET_VREG_R %eax %eax # eax<- vB 7036 movswl 2(rPC),%ecx # ecx<- ssssCCCC 7037 andb $0xf,rINSTbl # rINST<- A 7038 cmpl $0,%ecx 7039 je common_errDivideByZero 7040 cmpl $-1,%ecx 7041 jne .LOP_DIV_INT_LIT16_continue_div 7042 cmpl $0x80000000,%eax 7043 jne .LOP_DIV_INT_LIT16_continue_div 7044 movl $0x80000000,%eax 7045 SET_VREG %eax rINST 7046 UNSPILL(rIBASE) 7047 FETCH_INST_OPCODE 2 %ecx 7048 ADVANCE_PC 2 7049 GOTO_NEXT_R %ecx 7050 7051.LOP_DIV_INT_LIT16_continue_div: 7052 cltd 7053 idivl %ecx 7054 SET_VREG %eax rINST 7055 UNSPILL(rIBASE) 7056 FETCH_INST_OPCODE 2 %ecx 7057 ADVANCE_PC 2 7058 GOTO_NEXT_R %ecx 7059 7060 7061/* ------------------------------ */ 7062.L_OP_REM_INT_LIT16: /* 0xd4 */ 7063/* File: x86/OP_REM_INT_LIT16.S */ 7064/* File: x86/bindivLit16.S */ 7065 /* 7066 * 32-bit binary div/rem operation. Handles special case of op0=minint and 7067 * op1=-1. 7068 */ 7069 /* div/rem/lit16 vA, vB, #+CCCC */ 7070 /* Need A in rINST, ssssCCCC in ecx, vB in eax */ 7071 movzbl rINSTbl,%eax # eax<- 000000BA 7072 SPILL(rIBASE) 7073 sarl $4,%eax # eax<- B 7074 GET_VREG_R %eax %eax # eax<- vB 7075 movswl 2(rPC),%ecx # ecx<- ssssCCCC 7076 andb $0xf,rINSTbl # rINST<- A 7077 cmpl $0,%ecx 7078 je common_errDivideByZero 7079 cmpl $-1,%ecx 7080 jne .LOP_REM_INT_LIT16_continue_div 7081 cmpl $0x80000000,%eax 7082 jne .LOP_REM_INT_LIT16_continue_div 7083 movl $0,rIBASE 7084 SET_VREG rIBASE rINST 7085 UNSPILL(rIBASE) 7086 FETCH_INST_OPCODE 2 %ecx 7087 ADVANCE_PC 2 7088 GOTO_NEXT_R %ecx 7089 7090.LOP_REM_INT_LIT16_continue_div: 7091 cltd 7092 idivl %ecx 7093 SET_VREG rIBASE rINST 7094 UNSPILL(rIBASE) 7095 FETCH_INST_OPCODE 2 %ecx 7096 ADVANCE_PC 2 7097 GOTO_NEXT_R %ecx 7098 7099 7100/* ------------------------------ */ 7101.L_OP_AND_INT_LIT16: /* 0xd5 */ 7102/* File: x86/OP_AND_INT_LIT16.S */ 7103/* File: x86/binopLit16.S */ 7104 /* 7105 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 7106 * that specifies an instruction that performs "result = eax op ecx". 7107 * This could be an x86 instruction or a function call. (If the result 7108 * comes back in a register other than eax, you can override "result".) 7109 * 7110 * For: add-int/lit16, rsub-int, 7111 * and-int/lit16, or-int/lit16, xor-int/lit16 7112 */ 7113 /* binop/lit16 vA, vB, #+CCCC */ 7114 movzbl rINSTbl,%eax # eax<- 000000BA 7115 sarl $4,%eax # eax<- B 7116 GET_VREG_R %eax %eax # eax<- vB 7117 movswl 2(rPC),%ecx # ecx<- ssssCCCC 7118 andb $0xf,rINSTbl # rINST<- A 7119 andl %ecx,%eax # for example: addl %ecx, %eax 7120 SET_VREG %eax rINST 7121 FETCH_INST_OPCODE 2 %ecx 7122 ADVANCE_PC 2 7123 GOTO_NEXT_R %ecx 7124 7125 7126/* ------------------------------ */ 7127.L_OP_OR_INT_LIT16: /* 0xd6 */ 7128/* File: x86/OP_OR_INT_LIT16.S */ 7129/* File: x86/binopLit16.S */ 7130 /* 7131 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 7132 * that specifies an instruction that performs "result = eax op ecx". 7133 * This could be an x86 instruction or a function call. (If the result 7134 * comes back in a register other than eax, you can override "result".) 7135 * 7136 * For: add-int/lit16, rsub-int, 7137 * and-int/lit16, or-int/lit16, xor-int/lit16 7138 */ 7139 /* binop/lit16 vA, vB, #+CCCC */ 7140 movzbl rINSTbl,%eax # eax<- 000000BA 7141 sarl $4,%eax # eax<- B 7142 GET_VREG_R %eax %eax # eax<- vB 7143 movswl 2(rPC),%ecx # ecx<- ssssCCCC 7144 andb $0xf,rINSTbl # rINST<- A 7145 orl %ecx,%eax # for example: addl %ecx, %eax 7146 SET_VREG %eax rINST 7147 FETCH_INST_OPCODE 2 %ecx 7148 ADVANCE_PC 2 7149 GOTO_NEXT_R %ecx 7150 7151 7152/* ------------------------------ */ 7153.L_OP_XOR_INT_LIT16: /* 0xd7 */ 7154/* File: x86/OP_XOR_INT_LIT16.S */ 7155/* File: x86/binopLit16.S */ 7156 /* 7157 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 7158 * that specifies an instruction that performs "result = eax op ecx". 7159 * This could be an x86 instruction or a function call. (If the result 7160 * comes back in a register other than eax, you can override "result".) 7161 * 7162 * For: add-int/lit16, rsub-int, 7163 * and-int/lit16, or-int/lit16, xor-int/lit16 7164 */ 7165 /* binop/lit16 vA, vB, #+CCCC */ 7166 movzbl rINSTbl,%eax # eax<- 000000BA 7167 sarl $4,%eax # eax<- B 7168 GET_VREG_R %eax %eax # eax<- vB 7169 movswl 2(rPC),%ecx # ecx<- ssssCCCC 7170 andb $0xf,rINSTbl # rINST<- A 7171 xor %ecx,%eax # for example: addl %ecx, %eax 7172 SET_VREG %eax rINST 7173 FETCH_INST_OPCODE 2 %ecx 7174 ADVANCE_PC 2 7175 GOTO_NEXT_R %ecx 7176 7177 7178/* ------------------------------ */ 7179.L_OP_ADD_INT_LIT8: /* 0xd8 */ 7180/* File: x86/OP_ADD_INT_LIT8.S */ 7181/* File: x86/binopLit8.S */ 7182 /* 7183 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7184 * that specifies an instruction that performs "result = eax op ecx". 7185 * This could be an x86 instruction or a function call. (If the result 7186 * comes back in a register other than r0, you can override "result".) 7187 * 7188 * For: add-int/lit8, rsub-int/lit8 7189 * and-int/lit8, or-int/lit8, xor-int/lit8, 7190 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7191 */ 7192 /* binop/lit8 vAA, vBB, #+CC */ 7193 movzbl 2(rPC),%eax # eax<- BB 7194 movsbl 3(rPC),%ecx # ecx<- ssssssCC 7195 GET_VREG_R %eax %eax # eax<- rBB 7196 addl %ecx,%eax # ex: addl %ecx,%eax 7197 SET_VREG %eax rINST 7198 FETCH_INST_OPCODE 2 %ecx 7199 ADVANCE_PC 2 7200 GOTO_NEXT_R %ecx 7201 7202 7203/* ------------------------------ */ 7204.L_OP_RSUB_INT_LIT8: /* 0xd9 */ 7205/* File: x86/OP_RSUB_INT_LIT8.S */ 7206/* File: x86/binopLit8.S */ 7207 /* 7208 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7209 * that specifies an instruction that performs "result = eax op ecx". 7210 * This could be an x86 instruction or a function call. (If the result 7211 * comes back in a register other than r0, you can override "result".) 7212 * 7213 * For: add-int/lit8, rsub-int/lit8 7214 * and-int/lit8, or-int/lit8, xor-int/lit8, 7215 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7216 */ 7217 /* binop/lit8 vAA, vBB, #+CC */ 7218 movzbl 2(rPC),%eax # eax<- BB 7219 movsbl 3(rPC),%ecx # ecx<- ssssssCC 7220 GET_VREG_R %eax %eax # eax<- rBB 7221 subl %eax,%ecx # ex: addl %ecx,%eax 7222 SET_VREG %ecx rINST 7223 FETCH_INST_OPCODE 2 %ecx 7224 ADVANCE_PC 2 7225 GOTO_NEXT_R %ecx 7226 7227 7228/* ------------------------------ */ 7229.L_OP_MUL_INT_LIT8: /* 0xda */ 7230/* File: x86/OP_MUL_INT_LIT8.S */ 7231 /* mul/lit8 vAA, vBB, #+CC */ 7232 movzbl 2(rPC),%eax # eax<- BB 7233 movsbl 3(rPC),%ecx # ecx<- ssssssCC 7234 GET_VREG_R %eax %eax # eax<- rBB 7235 SPILL(rIBASE) 7236 imull %ecx,%eax # trashes rIBASE/edx 7237 UNSPILL(rIBASE) 7238 FETCH_INST_OPCODE 2 %ecx 7239 ADVANCE_PC 2 7240 SET_VREG %eax rINST 7241 GOTO_NEXT_R %ecx 7242 7243/* ------------------------------ */ 7244.L_OP_DIV_INT_LIT8: /* 0xdb */ 7245/* File: x86/OP_DIV_INT_LIT8.S */ 7246/* File: x86/bindivLit8.S */ 7247 /* 7248 * 32-bit div/rem "lit8" binary operation. Handles special case of 7249 * op0=minint & op1=-1 7250 */ 7251 /* div/rem/lit8 vAA, vBB, #+CC */ 7252 movzbl 2(rPC),%eax # eax<- BB 7253 movsbl 3(rPC),%ecx # ecx<- ssssssCC 7254 SPILL(rIBASE) 7255 GET_VREG_R %eax %eax # eax<- rBB 7256 cmpl $0,%ecx 7257 je common_errDivideByZero 7258 cmpl $0x80000000,%eax 7259 jne .LOP_DIV_INT_LIT8_continue_div 7260 cmpl $-1,%ecx 7261 jne .LOP_DIV_INT_LIT8_continue_div 7262 movl $0x80000000,%eax 7263 SET_VREG %eax rINST 7264 UNSPILL(rIBASE) 7265 FETCH_INST_OPCODE 2 %ecx 7266 ADVANCE_PC 2 7267 GOTO_NEXT_R %ecx 7268 7269.LOP_DIV_INT_LIT8_continue_div: 7270 cltd 7271 idivl %ecx 7272 SET_VREG %eax rINST 7273 UNSPILL(rIBASE) 7274 FETCH_INST_OPCODE 2 %ecx 7275 ADVANCE_PC 2 7276 GOTO_NEXT_R %ecx 7277 7278 7279/* ------------------------------ */ 7280.L_OP_REM_INT_LIT8: /* 0xdc */ 7281/* File: x86/OP_REM_INT_LIT8.S */ 7282/* File: x86/bindivLit8.S */ 7283 /* 7284 * 32-bit div/rem "lit8" binary operation. Handles special case of 7285 * op0=minint & op1=-1 7286 */ 7287 /* div/rem/lit8 vAA, vBB, #+CC */ 7288 movzbl 2(rPC),%eax # eax<- BB 7289 movsbl 3(rPC),%ecx # ecx<- ssssssCC 7290 SPILL(rIBASE) 7291 GET_VREG_R %eax %eax # eax<- rBB 7292 cmpl $0,%ecx 7293 je common_errDivideByZero 7294 cmpl $0x80000000,%eax 7295 jne .LOP_REM_INT_LIT8_continue_div 7296 cmpl $-1,%ecx 7297 jne .LOP_REM_INT_LIT8_continue_div 7298 movl $0,rIBASE 7299 SET_VREG rIBASE rINST 7300 UNSPILL(rIBASE) 7301 FETCH_INST_OPCODE 2 %ecx 7302 ADVANCE_PC 2 7303 GOTO_NEXT_R %ecx 7304 7305.LOP_REM_INT_LIT8_continue_div: 7306 cltd 7307 idivl %ecx 7308 SET_VREG rIBASE rINST 7309 UNSPILL(rIBASE) 7310 FETCH_INST_OPCODE 2 %ecx 7311 ADVANCE_PC 2 7312 GOTO_NEXT_R %ecx 7313 7314 7315/* ------------------------------ */ 7316.L_OP_AND_INT_LIT8: /* 0xdd */ 7317/* File: x86/OP_AND_INT_LIT8.S */ 7318/* File: x86/binopLit8.S */ 7319 /* 7320 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7321 * that specifies an instruction that performs "result = eax op ecx". 7322 * This could be an x86 instruction or a function call. (If the result 7323 * comes back in a register other than r0, you can override "result".) 7324 * 7325 * For: add-int/lit8, rsub-int/lit8 7326 * and-int/lit8, or-int/lit8, xor-int/lit8, 7327 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7328 */ 7329 /* binop/lit8 vAA, vBB, #+CC */ 7330 movzbl 2(rPC),%eax # eax<- BB 7331 movsbl 3(rPC),%ecx # ecx<- ssssssCC 7332 GET_VREG_R %eax %eax # eax<- rBB 7333 andl %ecx,%eax # ex: addl %ecx,%eax 7334 SET_VREG %eax rINST 7335 FETCH_INST_OPCODE 2 %ecx 7336 ADVANCE_PC 2 7337 GOTO_NEXT_R %ecx 7338 7339 7340/* ------------------------------ */ 7341.L_OP_OR_INT_LIT8: /* 0xde */ 7342/* File: x86/OP_OR_INT_LIT8.S */ 7343/* File: x86/binopLit8.S */ 7344 /* 7345 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7346 * that specifies an instruction that performs "result = eax op ecx". 7347 * This could be an x86 instruction or a function call. (If the result 7348 * comes back in a register other than r0, you can override "result".) 7349 * 7350 * For: add-int/lit8, rsub-int/lit8 7351 * and-int/lit8, or-int/lit8, xor-int/lit8, 7352 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7353 */ 7354 /* binop/lit8 vAA, vBB, #+CC */ 7355 movzbl 2(rPC),%eax # eax<- BB 7356 movsbl 3(rPC),%ecx # ecx<- ssssssCC 7357 GET_VREG_R %eax %eax # eax<- rBB 7358 orl %ecx,%eax # ex: addl %ecx,%eax 7359 SET_VREG %eax rINST 7360 FETCH_INST_OPCODE 2 %ecx 7361 ADVANCE_PC 2 7362 GOTO_NEXT_R %ecx 7363 7364 7365/* ------------------------------ */ 7366.L_OP_XOR_INT_LIT8: /* 0xdf */ 7367/* File: x86/OP_XOR_INT_LIT8.S */ 7368/* File: x86/binopLit8.S */ 7369 /* 7370 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7371 * that specifies an instruction that performs "result = eax op ecx". 7372 * This could be an x86 instruction or a function call. (If the result 7373 * comes back in a register other than r0, you can override "result".) 7374 * 7375 * For: add-int/lit8, rsub-int/lit8 7376 * and-int/lit8, or-int/lit8, xor-int/lit8, 7377 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7378 */ 7379 /* binop/lit8 vAA, vBB, #+CC */ 7380 movzbl 2(rPC),%eax # eax<- BB 7381 movsbl 3(rPC),%ecx # ecx<- ssssssCC 7382 GET_VREG_R %eax %eax # eax<- rBB 7383 xor %ecx,%eax # ex: addl %ecx,%eax 7384 SET_VREG %eax rINST 7385 FETCH_INST_OPCODE 2 %ecx 7386 ADVANCE_PC 2 7387 GOTO_NEXT_R %ecx 7388 7389 7390/* ------------------------------ */ 7391.L_OP_SHL_INT_LIT8: /* 0xe0 */ 7392/* File: x86/OP_SHL_INT_LIT8.S */ 7393/* File: x86/binopLit8.S */ 7394 /* 7395 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7396 * that specifies an instruction that performs "result = eax op ecx". 7397 * This could be an x86 instruction or a function call. (If the result 7398 * comes back in a register other than r0, you can override "result".) 7399 * 7400 * For: add-int/lit8, rsub-int/lit8 7401 * and-int/lit8, or-int/lit8, xor-int/lit8, 7402 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7403 */ 7404 /* binop/lit8 vAA, vBB, #+CC */ 7405 movzbl 2(rPC),%eax # eax<- BB 7406 movsbl 3(rPC),%ecx # ecx<- ssssssCC 7407 GET_VREG_R %eax %eax # eax<- rBB 7408 sall %cl,%eax # ex: addl %ecx,%eax 7409 SET_VREG %eax rINST 7410 FETCH_INST_OPCODE 2 %ecx 7411 ADVANCE_PC 2 7412 GOTO_NEXT_R %ecx 7413 7414 7415/* ------------------------------ */ 7416.L_OP_SHR_INT_LIT8: /* 0xe1 */ 7417/* File: x86/OP_SHR_INT_LIT8.S */ 7418/* File: x86/binopLit8.S */ 7419 /* 7420 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7421 * that specifies an instruction that performs "result = eax op ecx". 7422 * This could be an x86 instruction or a function call. (If the result 7423 * comes back in a register other than r0, you can override "result".) 7424 * 7425 * For: add-int/lit8, rsub-int/lit8 7426 * and-int/lit8, or-int/lit8, xor-int/lit8, 7427 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7428 */ 7429 /* binop/lit8 vAA, vBB, #+CC */ 7430 movzbl 2(rPC),%eax # eax<- BB 7431 movsbl 3(rPC),%ecx # ecx<- ssssssCC 7432 GET_VREG_R %eax %eax # eax<- rBB 7433 sarl %cl,%eax # ex: addl %ecx,%eax 7434 SET_VREG %eax rINST 7435 FETCH_INST_OPCODE 2 %ecx 7436 ADVANCE_PC 2 7437 GOTO_NEXT_R %ecx 7438 7439 7440/* ------------------------------ */ 7441.L_OP_USHR_INT_LIT8: /* 0xe2 */ 7442/* File: x86/OP_USHR_INT_LIT8.S */ 7443/* File: x86/binopLit8.S */ 7444 /* 7445 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7446 * that specifies an instruction that performs "result = eax op ecx". 7447 * This could be an x86 instruction or a function call. (If the result 7448 * comes back in a register other than r0, you can override "result".) 7449 * 7450 * For: add-int/lit8, rsub-int/lit8 7451 * and-int/lit8, or-int/lit8, xor-int/lit8, 7452 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7453 */ 7454 /* binop/lit8 vAA, vBB, #+CC */ 7455 movzbl 2(rPC),%eax # eax<- BB 7456 movsbl 3(rPC),%ecx # ecx<- ssssssCC 7457 GET_VREG_R %eax %eax # eax<- rBB 7458 shrl %cl,%eax # ex: addl %ecx,%eax 7459 SET_VREG %eax rINST 7460 FETCH_INST_OPCODE 2 %ecx 7461 ADVANCE_PC 2 7462 GOTO_NEXT_R %ecx 7463 7464 7465/* ------------------------------ */ 7466.L_OP_IGET_VOLATILE: /* 0xe3 */ 7467/* File: x86/OP_IGET_VOLATILE.S */ 7468/* File: x86/OP_IGET.S */ 7469 /* 7470 * General 32-bit instance field get. 7471 * 7472 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7473 */ 7474 /* op vA, vB, field@CCCC */ 7475 movl rSELF,%ecx 7476 SPILL(rIBASE) # preserve rIBASE 7477 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 7478 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 7479 movzbl rINSTbl,%ecx # ecx<- BA 7480 sarl $4,%ecx # ecx<- B 7481 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 7482 andb $0xf,rINSTbl # rINST<- A 7483 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 7484 movl (%eax,rIBASE,4),%eax # resolved entry 7485 testl %eax,%eax # is resolved entry null? 7486 jne .LOP_IGET_VOLATILE_finish # no, already resolved 7487 movl rIBASE,OUT_ARG1(%esp) # needed by dvmResolveInstField 7488 movl rSELF,rIBASE 7489 EXPORT_PC 7490 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 7491 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 7492 SPILL_TMP1(%ecx) # save obj pointer across call 7493 movl rIBASE,OUT_ARG0(%esp) # pass in method->clazz 7494 call dvmResolveInstField # ... to dvmResolveInstField 7495 UNSPILL_TMP1(%ecx) 7496 testl %eax,%eax # returns InstrField ptr 7497 jne .LOP_IGET_VOLATILE_finish 7498 jmp common_exceptionThrown 7499 7500.LOP_IGET_VOLATILE_finish: 7501 /* 7502 * Currently: 7503 * eax holds resolved field 7504 * ecx holds object 7505 * rINST holds A 7506 */ 7507 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 7508 testl %ecx,%ecx # object null? 7509 je common_errNullObject # object was null 7510 movl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 7511 FETCH_INST_OPCODE 2 %eax 7512 UNSPILL(rIBASE) 7513 SET_VREG %ecx rINST 7514 ADVANCE_PC 2 7515 GOTO_NEXT_R %eax 7516 7517 7518/* ------------------------------ */ 7519.L_OP_IPUT_VOLATILE: /* 0xe4 */ 7520/* File: x86/OP_IPUT_VOLATILE.S */ 7521/* File: x86/OP_IPUT.S */ 7522 7523 /* 7524 * General 32-bit instance field put. 7525 * 7526 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 7527 */ 7528 /* op vA, vB, field@CCCC */ 7529 movl rSELF,%ecx 7530 SPILL (rIBASE) 7531 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 7532 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 7533 movzbl rINSTbl,%ecx # ecx<- BA 7534 sarl $4,%ecx # ecx<- B 7535 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 7536 andb $0xf,rINSTbl # rINST<- A 7537 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 7538 movl (%eax,rIBASE,4),%eax # resolved entry 7539 testl %eax,%eax # is resolved entry null? 7540 jne .LOP_IPUT_VOLATILE_finish # no, already resolved 7541 movl rIBASE,OUT_ARG1(%esp) 7542 movl rSELF,rIBASE 7543 EXPORT_PC 7544 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 7545 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 7546 SPILL_TMP1(%ecx) # save obj pointer across call 7547 movl rIBASE,OUT_ARG0(%esp) # pass in method->clazz 7548 call dvmResolveInstField # ... to dvmResolveInstField 7549 UNSPILL_TMP1(%ecx) 7550 testl %eax,%eax # returns InstrField ptr 7551 jne .LOP_IPUT_VOLATILE_finish 7552 jmp common_exceptionThrown 7553 7554.LOP_IPUT_VOLATILE_finish: 7555 /* 7556 * Currently: 7557 * eax holds resolved field 7558 * ecx holds object 7559 * rINST holds A 7560 */ 7561 GET_VREG_R rINST rINST # rINST<- v[A] 7562 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 7563 testl %ecx,%ecx # object null? 7564 je common_errNullObject # object was null 7565 movl rINST,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 7566 FETCH_INST_OPCODE 2 %ecx 7567 UNSPILL(rIBASE) 7568 ADVANCE_PC 2 7569 GOTO_NEXT_R %ecx 7570 7571 7572/* ------------------------------ */ 7573.L_OP_SGET_VOLATILE: /* 0xe5 */ 7574/* File: x86/OP_SGET_VOLATILE.S */ 7575/* File: x86/OP_SGET.S */ 7576 /* 7577 * General 32-bit SGET handler. 7578 * 7579 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7580 */ 7581 /* op vAA, field@BBBB */ 7582 movl rSELF,%ecx 7583 movzwl 2(rPC),%eax # eax<- field ref BBBB 7584 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7585 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7586#if defined(WITH_JIT) 7587 movl %ecx, TMP_SPILL1(%ebp) 7588 lea (%ecx,%eax,4),%ecx 7589 movl %ecx, TMP_SPILL2(%ebp) 7590 movl TMP_SPILL1(%ebp), %ecx 7591#endif 7592 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7593 testl %eax,%eax # resolved entry null? 7594 je .LOP_SGET_VOLATILE_resolve # if not, make it so 7595.LOP_SGET_VOLATILE_finish: # field ptr in eax 7596 movl offStaticField_value(%eax),%eax 7597 FETCH_INST_OPCODE 2 %ecx 7598 ADVANCE_PC 2 7599 SET_VREG %eax rINST 7600 GOTO_NEXT_R %ecx 7601 7602 /* 7603 * Go resolve the field 7604 */ 7605.LOP_SGET_VOLATILE_resolve: 7606 movl rSELF,%ecx 7607 movzwl 2(rPC),%eax # eax<- field ref BBBB 7608 movl offThread_method(%ecx),%ecx # ecx<- current method 7609 EXPORT_PC # could throw, need to export 7610 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 7611 movl %eax,OUT_ARG1(%esp) 7612 movl %ecx,OUT_ARG0(%esp) 7613 SPILL(rIBASE) 7614 call dvmResolveStaticField # eax<- resolved StaticField ptr 7615 UNSPILL(rIBASE) 7616 testl %eax,%eax 7617 je common_exceptionThrown # no, handle exception 7618#if defined(WITH_JIT) 7619 movl TMP_SPILL2(%ebp), %ecx 7620 SPILL(rIBASE) 7621 call common_verifyField 7622 UNSPILL(rIBASE) 7623#endif 7624 jmp .LOP_SGET_VOLATILE_finish # success, continue 7625 7626 7627/* ------------------------------ */ 7628.L_OP_SPUT_VOLATILE: /* 0xe6 */ 7629/* File: x86/OP_SPUT_VOLATILE.S */ 7630/* File: x86/OP_SPUT.S */ 7631 /* 7632 * General 32-bit SPUT handler. 7633 * 7634 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 7635 */ 7636 /* op vAA, field@BBBB */ 7637 movl rSELF,%ecx 7638 movzwl 2(rPC),%eax # eax<- field ref BBBB 7639 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7640 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7641#if defined(WITH_JIT) 7642 movl %ecx, TMP_SPILL1(%ebp) 7643 lea (%ecx,%eax,4),%ecx 7644 movl %ecx, TMP_SPILL2(%ebp) 7645 movl TMP_SPILL1(%ebp), %ecx 7646#endif 7647 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7648 testl %eax,%eax # resolved entry null? 7649 je .LOP_SPUT_VOLATILE_resolve # if not, make it so 7650.LOP_SPUT_VOLATILE_finish: # field ptr in eax 7651 GET_VREG_R rINST rINST 7652 FETCH_INST_OPCODE 2 %ecx 7653 ADVANCE_PC 2 7654 movl rINST,offStaticField_value(%eax) 7655 GOTO_NEXT_R %ecx 7656 7657 /* 7658 * Go resolve the field 7659 */ 7660.LOP_SPUT_VOLATILE_resolve: 7661 movl rSELF,%ecx 7662 movzwl 2(rPC),%eax # eax<- field ref BBBB 7663 movl offThread_method(%ecx),%ecx # ecx<- current method 7664 EXPORT_PC # could throw, need to export 7665 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 7666 movl %eax,OUT_ARG1(%esp) 7667 movl %ecx,OUT_ARG0(%esp) 7668 SPILL(rIBASE) 7669 call dvmResolveStaticField # eax<- resolved StaticField ptr 7670 UNSPILL(rIBASE) 7671 testl %eax,%eax 7672 je common_exceptionThrown # no, handle exception 7673#if defined(WITH_JIT) 7674 movl TMP_SPILL2(%ebp), %ecx 7675 SPILL(rIBASE) 7676 call common_verifyField 7677 UNSPILL(rIBASE) 7678#endif 7679 jmp .LOP_SPUT_VOLATILE_finish # success, continue 7680 7681/* ------------------------------ */ 7682.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 7683/* File: x86/OP_IGET_OBJECT_VOLATILE.S */ 7684/* File: x86/OP_IGET.S */ 7685 /* 7686 * General 32-bit instance field get. 7687 * 7688 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7689 */ 7690 /* op vA, vB, field@CCCC */ 7691 movl rSELF,%ecx 7692 SPILL(rIBASE) # preserve rIBASE 7693 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 7694 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 7695 movzbl rINSTbl,%ecx # ecx<- BA 7696 sarl $4,%ecx # ecx<- B 7697 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 7698 andb $0xf,rINSTbl # rINST<- A 7699 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 7700 movl (%eax,rIBASE,4),%eax # resolved entry 7701 testl %eax,%eax # is resolved entry null? 7702 jne .LOP_IGET_OBJECT_VOLATILE_finish # no, already resolved 7703 movl rIBASE,OUT_ARG1(%esp) # needed by dvmResolveInstField 7704 movl rSELF,rIBASE 7705 EXPORT_PC 7706 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 7707 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 7708 SPILL_TMP1(%ecx) # save obj pointer across call 7709 movl rIBASE,OUT_ARG0(%esp) # pass in method->clazz 7710 call dvmResolveInstField # ... to dvmResolveInstField 7711 UNSPILL_TMP1(%ecx) 7712 testl %eax,%eax # returns InstrField ptr 7713 jne .LOP_IGET_OBJECT_VOLATILE_finish 7714 jmp common_exceptionThrown 7715 7716.LOP_IGET_OBJECT_VOLATILE_finish: 7717 /* 7718 * Currently: 7719 * eax holds resolved field 7720 * ecx holds object 7721 * rINST holds A 7722 */ 7723 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 7724 testl %ecx,%ecx # object null? 7725 je common_errNullObject # object was null 7726 movl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 7727 FETCH_INST_OPCODE 2 %eax 7728 UNSPILL(rIBASE) 7729 SET_VREG %ecx rINST 7730 ADVANCE_PC 2 7731 GOTO_NEXT_R %eax 7732 7733 7734/* ------------------------------ */ 7735.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 7736 /* (stub) */ 7737 SAVE_PC_FP_TO_SELF %ecx # leaves rSELF in %ecx 7738 movl %ecx,OUT_ARG0(%esp) # self is first arg to function 7739 call dvmMterp_OP_IGET_WIDE_VOLATILE # do the real work 7740 movl rSELF,%ecx 7741 LOAD_PC_FP_FROM_SELF # retrieve updated values 7742 movl offThread_curHandlerTable(%ecx),rIBASE # set up rIBASE 7743 FETCH_INST 7744 GOTO_NEXT 7745/* ------------------------------ */ 7746.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 7747 /* (stub) */ 7748 SAVE_PC_FP_TO_SELF %ecx # leaves rSELF in %ecx 7749 movl %ecx,OUT_ARG0(%esp) # self is first arg to function 7750 call dvmMterp_OP_IPUT_WIDE_VOLATILE # do the real work 7751 movl rSELF,%ecx 7752 LOAD_PC_FP_FROM_SELF # retrieve updated values 7753 movl offThread_curHandlerTable(%ecx),rIBASE # set up rIBASE 7754 FETCH_INST 7755 GOTO_NEXT 7756/* ------------------------------ */ 7757.L_OP_SGET_WIDE_VOLATILE: /* 0xea */ 7758 /* (stub) */ 7759 SAVE_PC_FP_TO_SELF %ecx # leaves rSELF in %ecx 7760 movl %ecx,OUT_ARG0(%esp) # self is first arg to function 7761 call dvmMterp_OP_SGET_WIDE_VOLATILE # do the real work 7762 movl rSELF,%ecx 7763 LOAD_PC_FP_FROM_SELF # retrieve updated values 7764 movl offThread_curHandlerTable(%ecx),rIBASE # set up rIBASE 7765 FETCH_INST 7766 GOTO_NEXT 7767/* ------------------------------ */ 7768.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 7769 /* (stub) */ 7770 SAVE_PC_FP_TO_SELF %ecx # leaves rSELF in %ecx 7771 movl %ecx,OUT_ARG0(%esp) # self is first arg to function 7772 call dvmMterp_OP_SPUT_WIDE_VOLATILE # do the real work 7773 movl rSELF,%ecx 7774 LOAD_PC_FP_FROM_SELF # retrieve updated values 7775 movl offThread_curHandlerTable(%ecx),rIBASE # set up rIBASE 7776 FETCH_INST 7777 GOTO_NEXT 7778/* ------------------------------ */ 7779.L_OP_BREAKPOINT: /* 0xec */ 7780/* File: x86/OP_BREAKPOINT.S */ 7781 /* 7782 * Breakpoint handler. 7783 * 7784 * Restart this instruction with the original opcode. By 7785 * the time we get here, the breakpoint will have already been 7786 * handled. We also assume that all other special "checkBefore" 7787 * actions have been handled, so we'll transition directly 7788 * to the real handler 7789 */ 7790 SPILL(rIBASE) 7791 movl rPC,OUT_ARG0(%esp) 7792 call dvmGetOriginalOpcode 7793 UNSPILL(rIBASE) 7794 movl rSELF,%ecx 7795 movzbl 1(rPC),rINST 7796 movl offThread_mainHandlerTable(%ecx),%ecx 7797 jmp *(%ecx,%eax,4) 7798 7799 7800/* ------------------------------ */ 7801.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 7802/* File: x86/OP_THROW_VERIFICATION_ERROR.S */ 7803 /* 7804 * Handle a throw-verification-error instruction. This throws an 7805 * exception for an error discovered during verification. The 7806 * exception is indicated by AA, with some detail provided by BBBB. 7807 */ 7808 /* op AA, ref@BBBB */ 7809 movl rSELF,%ecx 7810 movzwl 2(rPC),%eax # eax<- BBBB 7811 movl offThread_method(%ecx),%ecx # ecx<- self->method 7812 EXPORT_PC 7813 movl %eax,OUT_ARG2(%esp) # arg2<- BBBB 7814 movl rINST,OUT_ARG1(%esp) # arg1<- AA 7815 movl %ecx,OUT_ARG0(%esp) # arg0<- method 7816 call dvmThrowVerificationError # call(method, kind, ref) 7817 jmp common_exceptionThrown # handle exception 7818 7819/* ------------------------------ */ 7820.L_OP_EXECUTE_INLINE: /* 0xee */ 7821/* File: x86/OP_EXECUTE_INLINE.S */ 7822 /* 7823 * Execute a "native inline" instruction. 7824 * 7825 * We will be calling through a function table: 7826 * 7827 * (*gDvmInlineOpsTable[opIndex].func)(arg0, arg1, arg2, arg3, pResult) 7828 * 7829 * Ignores argument count - always loads 4. 7830 * 7831 */ 7832 /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */ 7833 movl rSELF,%ecx 7834 EXPORT_PC 7835 movzwl 2(rPC),%eax # eax<- BBBB 7836 SPILL(rIBASE) # preserve rIBASE 7837 movl offThread_subMode(%ecx), %edx # edx<- submode flags 7838 andl $kSubModeDebugProfile, %edx # debug or profile mode active? 7839 jnz .LOP_EXECUTE_INLINE_debugprofile # yes, take slow path 7840.LOP_EXECUTE_INLINE_resume: 7841 leal offThread_retval(%ecx),%ecx # ecx<- &self->retval 7842 movl %ecx,OUT_ARG4(%esp) 7843 call .LOP_EXECUTE_INLINE_continue # make call; will return after 7844 UNSPILL(rIBASE) # restore rIBASE 7845 testl %eax,%eax # successful? 7846 jz common_exceptionThrown # no, handle exception 7847 FETCH_INST_OPCODE 3 %ecx 7848 ADVANCE_PC 3 7849 GOTO_NEXT_R %ecx 7850 7851.LOP_EXECUTE_INLINE_continue: 7852 /* 7853 * Extract args, call function. 7854 * ecx = #of args (0-4) 7855 * eax = call index 7856 * @esp = return addr 7857 * esp is -4 from normal 7858 * 7859 * Go ahead and load all 4 args, even if not used. 7860 */ 7861 movzwl 4(rPC),rIBASE 7862 7863 movl $0xf,%ecx 7864 andl rIBASE,%ecx 7865 GET_VREG_R %ecx %ecx 7866 sarl $4,rIBASE 7867 movl %ecx,4+OUT_ARG0(%esp) 7868 7869 movl $0xf,%ecx 7870 andl rIBASE,%ecx 7871 GET_VREG_R %ecx %ecx 7872 sarl $4,rIBASE 7873 movl %ecx,4+OUT_ARG1(%esp) 7874 7875 movl $0xf,%ecx 7876 andl rIBASE,%ecx 7877 GET_VREG_R %ecx %ecx 7878 sarl $4,rIBASE 7879 movl %ecx,4+OUT_ARG2(%esp) 7880 7881 movl $0xf,%ecx 7882 andl rIBASE,%ecx 7883 GET_VREG_R %ecx %ecx 7884 sarl $4,rIBASE 7885 movl %ecx,4+OUT_ARG3(%esp) 7886 7887 sall $4,%eax # index *= sizeof(table entry) 7888 jmp *gDvmInlineOpsTable(%eax) 7889 # will return to caller of .LOP_EXECUTE_INLINE_continue 7890 7891 /* 7892 * We're debugging or profiling. 7893 * eax: opIndex 7894 */ 7895.LOP_EXECUTE_INLINE_debugprofile: 7896 movl %eax,OUT_ARG0(%esp) # arg0<- BBBB 7897 SPILL_TMP1(%eax) # save opIndex 7898 call dvmResolveInlineNative # dvmResolveInlineNative(opIndex) 7899 movl rSELF,%ecx # restore self 7900 testl %eax,%eax # method resolved? 7901 movl %eax,%edx # save possibly resolved method in edx 7902 UNSPILL_TMP1(%eax) # in case not resolved, restore opIndex 7903 jz .LOP_EXECUTE_INLINE_resume # not resolved, just move on 7904 SPILL_TMP2(%edx) # save method 7905 movl %edx,OUT_ARG0(%esp) # arg0<- method 7906 movl %ecx,OUT_ARG1(%esp) # arg1<- self 7907 call dvmFastMethodTraceEnter # dvmFastMethodTraceEnter(method,self) 7908 movl rSELF,%ecx # restore self 7909 UNSPILL_TMP1(%eax) # restore opIndex 7910 leal offThread_retval(%ecx),%ecx # ecx<- &self->retval 7911 movl %ecx,OUT_ARG4(%esp) # needed for pResult of inline operation handler 7912 call .LOP_EXECUTE_INLINE_continue # make call; will return after 7913 SPILL_TMP1(%eax) # save result of inline 7914 UNSPILL_TMP2(%eax) # restore method 7915 movl rSELF,%ecx # restore self 7916 movl %eax,OUT_ARG0(%esp) # arg0<- method 7917 movl %ecx,OUT_ARG1(%esp) # arg1<- self 7918 call dvmFastNativeMethodTraceExit # dvmFastNativeMethodTraceExit(method,self) 7919 UNSPILL(rIBASE) # restore rIBASE 7920 UNSPILL_TMP1(%eax) # restore result of inline 7921 testl %eax,%eax # successful? 7922 jz common_exceptionThrown # no, handle exception 7923 FETCH_INST_OPCODE 3 %ecx 7924 ADVANCE_PC 3 7925 GOTO_NEXT_R %ecx 7926 7927/* ------------------------------ */ 7928.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 7929 /* (stub) */ 7930 SAVE_PC_FP_TO_SELF %ecx # leaves rSELF in %ecx 7931 movl %ecx,OUT_ARG0(%esp) # self is first arg to function 7932 call dvmMterp_OP_EXECUTE_INLINE_RANGE # do the real work 7933 movl rSELF,%ecx 7934 LOAD_PC_FP_FROM_SELF # retrieve updated values 7935 movl offThread_curHandlerTable(%ecx),rIBASE # set up rIBASE 7936 FETCH_INST 7937 GOTO_NEXT 7938/* ------------------------------ */ 7939.L_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */ 7940 /* (stub) */ 7941 SAVE_PC_FP_TO_SELF %ecx # leaves rSELF in %ecx 7942 movl %ecx,OUT_ARG0(%esp) # self is first arg to function 7943 call dvmMterp_OP_INVOKE_OBJECT_INIT_RANGE # do the real work 7944 movl rSELF,%ecx 7945 LOAD_PC_FP_FROM_SELF # retrieve updated values 7946 movl offThread_curHandlerTable(%ecx),rIBASE # set up rIBASE 7947 FETCH_INST 7948 GOTO_NEXT 7949/* ------------------------------ */ 7950.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 7951 /* (stub) */ 7952 SAVE_PC_FP_TO_SELF %ecx # leaves rSELF in %ecx 7953 movl %ecx,OUT_ARG0(%esp) # self is first arg to function 7954 call dvmMterp_OP_RETURN_VOID_BARRIER # do the real work 7955 movl rSELF,%ecx 7956 LOAD_PC_FP_FROM_SELF # retrieve updated values 7957 movl offThread_curHandlerTable(%ecx),rIBASE # set up rIBASE 7958 FETCH_INST 7959 GOTO_NEXT 7960/* ------------------------------ */ 7961.L_OP_IGET_QUICK: /* 0xf2 */ 7962/* File: x86/OP_IGET_QUICK.S */ 7963 /* For: iget-quick, iget-object-quick */ 7964 /* op vA, vB, offset@CCCC */ 7965 movzbl rINSTbl,%ecx # ecx<- BA 7966 sarl $4,%ecx # ecx<- B 7967 GET_VREG_R %ecx %ecx # vB (object we're operating on) 7968 movzwl 2(rPC),%eax # eax<- field byte offset 7969 cmpl $0,%ecx # is object null? 7970 je common_errNullObject 7971 movl (%ecx,%eax,1),%eax 7972 FETCH_INST_OPCODE 2 %ecx 7973 ADVANCE_PC 2 7974 andb $0xf,rINSTbl # rINST<- A 7975 SET_VREG %eax rINST # fp[A]<- result 7976 GOTO_NEXT_R %ecx 7977 7978/* ------------------------------ */ 7979.L_OP_IGET_WIDE_QUICK: /* 0xf3 */ 7980/* File: x86/OP_IGET_WIDE_QUICK.S */ 7981 /* For: iget-wide-quick */ 7982 /* op vA, vB, offset@CCCC */ 7983 movzbl rINSTbl,%ecx # ecx<- BA 7984 sarl $4,%ecx # ecx<- B 7985 GET_VREG_R %ecx %ecx # vB (object we're operating on) 7986 movzwl 2(rPC),%eax # eax<- field byte offset 7987 cmpl $0,%ecx # is object null? 7988 je common_errNullObject 7989 leal (%ecx,%eax,1),%eax # eax<- address of 64-bit source 7990 movl (%eax),%ecx # ecx<- lsw 7991 movl 4(%eax),%eax # eax<- msw 7992 andb $0xf,rINSTbl # rINST<- A 7993 SET_VREG_WORD %ecx rINST 0 # v[A+0]<- lsw 7994 FETCH_INST_OPCODE 2 %ecx 7995 SET_VREG_WORD %eax rINST 1 # v[A+1]<- msw 7996 ADVANCE_PC 2 7997 GOTO_NEXT_R %ecx 7998 7999/* ------------------------------ */ 8000.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 8001/* File: x86/OP_IGET_OBJECT_QUICK.S */ 8002/* File: x86/OP_IGET_QUICK.S */ 8003 /* For: iget-quick, iget-object-quick */ 8004 /* op vA, vB, offset@CCCC */ 8005 movzbl rINSTbl,%ecx # ecx<- BA 8006 sarl $4,%ecx # ecx<- B 8007 GET_VREG_R %ecx %ecx # vB (object we're operating on) 8008 movzwl 2(rPC),%eax # eax<- field byte offset 8009 cmpl $0,%ecx # is object null? 8010 je common_errNullObject 8011 movl (%ecx,%eax,1),%eax 8012 FETCH_INST_OPCODE 2 %ecx 8013 ADVANCE_PC 2 8014 andb $0xf,rINSTbl # rINST<- A 8015 SET_VREG %eax rINST # fp[A]<- result 8016 GOTO_NEXT_R %ecx 8017 8018 8019/* ------------------------------ */ 8020.L_OP_IPUT_QUICK: /* 0xf5 */ 8021/* File: x86/OP_IPUT_QUICK.S */ 8022 /* For: iput-quick */ 8023 /* op vA, vB, offset@CCCC */ 8024 movzbl rINSTbl,%ecx # ecx<- BA 8025 sarl $4,%ecx # ecx<- B 8026 GET_VREG_R %ecx %ecx # vB (object we're operating on) 8027 andb $0xf,rINSTbl # rINST<- A 8028 GET_VREG_R rINST,rINST # rINST<- v[A] 8029 movzwl 2(rPC),%eax # eax<- field byte offset 8030 testl %ecx,%ecx # is object null? 8031 je common_errNullObject 8032 movl rINST,(%ecx,%eax,1) 8033 FETCH_INST_OPCODE 2 %ecx 8034 ADVANCE_PC 2 8035 GOTO_NEXT_R %ecx 8036 8037/* ------------------------------ */ 8038.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 8039/* File: x86/OP_IPUT_WIDE_QUICK.S */ 8040 /* For: iput-wide-quick */ 8041 /* op vA, vB, offset@CCCC */ 8042 movzbl rINSTbl,%ecx # ecx<- BA 8043 sarl $4,%ecx # ecx<- B 8044 GET_VREG_R %ecx %ecx # vB (object we're operating on) 8045 movzwl 2(rPC),%eax # eax<- field byte offset 8046 testl %ecx,%ecx # is object null? 8047 je common_errNullObject 8048 leal (%ecx,%eax,1),%ecx # ecx<- Address of 64-bit target 8049 andb $0xf,rINSTbl # rINST<- A 8050 GET_VREG_WORD %eax rINST 0 # eax<- lsw 8051 GET_VREG_WORD rINST rINST 1 # rINST<- msw 8052 movl %eax,(%ecx) 8053 movl rINST,4(%ecx) 8054 FETCH_INST_OPCODE 2 %ecx 8055 ADVANCE_PC 2 8056 GOTO_NEXT_R %ecx 8057 8058/* ------------------------------ */ 8059.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 8060/* File: x86/OP_IPUT_OBJECT_QUICK.S */ 8061 /* For: iput-object-quick */ 8062 /* op vA, vB, offset@CCCC */ 8063 movzbl rINSTbl,%ecx # ecx<- BA 8064 sarl $4,%ecx # ecx<- B 8065 GET_VREG_R %ecx %ecx # vB (object we're operating on) 8066 andb $0xf,rINSTbl # rINST<- A 8067 GET_VREG_R rINST rINST # rINST<- v[A] 8068 movzwl 2(rPC),%eax # eax<- field byte offset 8069 testl %ecx,%ecx # is object null? 8070 je common_errNullObject 8071 movl rINST,(%ecx,%eax,1) 8072 movl rSELF,%eax 8073 testl rINST,rINST # did we store null? 8074 movl offThread_cardTable(%eax),%eax # get card table base 8075 je 1f # skip card mark if null store 8076 shrl $GC_CARD_SHIFT,%ecx # object head to card number 8077 movb %al,(%eax,%ecx) # mark card based on object head 80781: 8079 FETCH_INST_OPCODE 2 %ecx 8080 ADVANCE_PC 2 8081 GOTO_NEXT_R %ecx 8082 8083/* ------------------------------ */ 8084.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 8085/* File: x86/OP_INVOKE_VIRTUAL_QUICK.S */ 8086 /* 8087 * Handle an optimized virtual method call. 8088 * 8089 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 8090 */ 8091 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 8092 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 8093 movzwl 4(rPC),%ecx # eax<- FEDC or CCCC 8094 movzwl 2(rPC),%edx # ecx<- BBBB 8095 .if (!0) 8096 andl $0xf,%ecx # eax<- C (or stays CCCC) 8097 .endif 8098 GET_VREG_R %ecx %ecx # ecx<- vC ("this" ptr) 8099 testl %ecx,%ecx # null? 8100 je common_errNullObject # yep, throw exception 8101 movl offObject_clazz(%ecx),%eax # eax<- thisPtr->clazz 8102 movl offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable 8103 EXPORT_PC # might throw later - get ready 8104 movl (%eax,%edx,4),%eax # eax<- vtable[BBBB] 8105 jmp common_invokeMethodNoRange 8106 8107/* ------------------------------ */ 8108.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 8109/* File: x86/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */ 8110/* File: x86/OP_INVOKE_VIRTUAL_QUICK.S */ 8111 /* 8112 * Handle an optimized virtual method call. 8113 * 8114 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 8115 */ 8116 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 8117 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 8118 movzwl 4(rPC),%ecx # eax<- FEDC or CCCC 8119 movzwl 2(rPC),%edx # ecx<- BBBB 8120 .if (!1) 8121 andl $0xf,%ecx # eax<- C (or stays CCCC) 8122 .endif 8123 GET_VREG_R %ecx %ecx # ecx<- vC ("this" ptr) 8124 testl %ecx,%ecx # null? 8125 je common_errNullObject # yep, throw exception 8126 movl offObject_clazz(%ecx),%eax # eax<- thisPtr->clazz 8127 movl offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable 8128 EXPORT_PC # might throw later - get ready 8129 movl (%eax,%edx,4),%eax # eax<- vtable[BBBB] 8130 jmp common_invokeMethodRange 8131 8132 8133/* ------------------------------ */ 8134.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 8135/* File: x86/OP_INVOKE_SUPER_QUICK.S */ 8136 /* 8137 * Handle an optimized "super" method call. 8138 * 8139 * for: [opt] invoke-super-quick, invoke-super-quick/range 8140 */ 8141 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 8142 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 8143 movl rSELF,%ecx 8144 movzwl 4(rPC),%eax # eax<- GFED or CCCC 8145 movl offThread_method(%ecx),%ecx # ecx<- current method 8146 .if (!0) 8147 andl $0xf,%eax # eax<- D (or stays CCCC) 8148 .endif 8149 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 8150 GET_VREG_R %eax %eax # eax<- "this" 8151 movl offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super 8152 testl %eax,%eax # null "this"? 8153 je common_errNullObject # "this" is null, throw exception 8154 movl %eax, TMP_SPILL1(%ebp) 8155 movzwl 2(rPC),%eax # eax<- BBBB 8156 movl offClassObject_vtable(%ecx),%ecx # ecx<- vtable 8157 EXPORT_PC 8158 movl (%ecx,%eax,4),%eax # eax<- super->vtable[BBBB] 8159 movl TMP_SPILL1(%ebp), %ecx 8160 jmp common_invokeMethodNoRange 8161 8162/* ------------------------------ */ 8163.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 8164/* File: x86/OP_INVOKE_SUPER_QUICK_RANGE.S */ 8165/* File: x86/OP_INVOKE_SUPER_QUICK.S */ 8166 /* 8167 * Handle an optimized "super" method call. 8168 * 8169 * for: [opt] invoke-super-quick, invoke-super-quick/range 8170 */ 8171 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 8172 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 8173 movl rSELF,%ecx 8174 movzwl 4(rPC),%eax # eax<- GFED or CCCC 8175 movl offThread_method(%ecx),%ecx # ecx<- current method 8176 .if (!1) 8177 andl $0xf,%eax # eax<- D (or stays CCCC) 8178 .endif 8179 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 8180 GET_VREG_R %eax %eax # eax<- "this" 8181 movl offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super 8182 testl %eax,%eax # null "this"? 8183 je common_errNullObject # "this" is null, throw exception 8184 movl %eax, TMP_SPILL1(%ebp) 8185 movzwl 2(rPC),%eax # eax<- BBBB 8186 movl offClassObject_vtable(%ecx),%ecx # ecx<- vtable 8187 EXPORT_PC 8188 movl (%ecx,%eax,4),%eax # eax<- super->vtable[BBBB] 8189 movl TMP_SPILL1(%ebp), %ecx 8190 jmp common_invokeMethodRange 8191 8192 8193/* ------------------------------ */ 8194.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 8195/* File: x86/OP_IPUT_OBJECT_VOLATILE.S */ 8196/* File: x86/OP_IPUT_OBJECT.S */ 8197 /* 8198 * Object field put. 8199 * 8200 * for: iput-object 8201 */ 8202 /* op vA, vB, field@CCCC */ 8203 movl rSELF,%ecx 8204 SPILL(rIBASE) 8205 movzwl 2(rPC),rIBASE # rIBASE<- 0000CCCC 8206 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 8207 movzbl rINSTbl,%ecx # ecx<- BA 8208 sarl $4,%ecx # ecx<- B 8209 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 8210 andb $0xf,rINSTbl # rINST<- A 8211 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 8212 movl (%eax,rIBASE,4),%eax # resolved entry 8213 testl %eax,%eax # is resolved entry null? 8214 jne .LOP_IPUT_OBJECT_VOLATILE_finish # no, already resolved 8215 movl rIBASE,OUT_ARG1(%esp) 8216 movl rSELF,rIBASE 8217 EXPORT_PC 8218 movl offThread_method(rIBASE),rIBASE # rIBASE<- current method 8219 movl offMethod_clazz(rIBASE),rIBASE # rIBASE<- method->clazz 8220 SPILL_TMP1(%ecx) # save obj pointer across call 8221 movl rIBASE,OUT_ARG0(%esp) # pass in method->clazz 8222 call dvmResolveInstField # ... to dvmResolveInstField 8223 UNSPILL_TMP1(%ecx) 8224 testl %eax,%eax # returns InstrField ptr 8225 jne .LOP_IPUT_OBJECT_VOLATILE_finish 8226 jmp common_exceptionThrown 8227 8228.LOP_IPUT_OBJECT_VOLATILE_finish: 8229 /* 8230 * Currently: 8231 * eax holds resolved field 8232 * ecx holds object 8233 * rIBASE is scratch, but needs to be unspilled 8234 * rINST holds A 8235 */ 8236 GET_VREG_R rINST rINST # rINST<- v[A] 8237 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 8238 testl %ecx,%ecx # object null? 8239 je common_errNullObject # object was null 8240 movl rINST,(%ecx,%eax) # obj.field <- v[A](8/16/32 bits) 8241 movl rSELF,%eax 8242 testl rINST,rINST # stored a NULL? 8243 movl offThread_cardTable(%eax),%eax # get card table base 8244 je 1f # skip card mark if null store 8245 shrl $GC_CARD_SHIFT,%ecx # object head to card number 8246 movb %al,(%eax,%ecx) # mark card using object head 82471: 8248 UNSPILL(rIBASE) 8249 FETCH_INST_OPCODE 2 %ecx 8250 ADVANCE_PC 2 8251 GOTO_NEXT_R %ecx 8252 8253 8254/* ------------------------------ */ 8255.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 8256/* File: x86/OP_SGET_OBJECT_VOLATILE.S */ 8257/* File: x86/OP_SGET.S */ 8258 /* 8259 * General 32-bit SGET handler. 8260 * 8261 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 8262 */ 8263 /* op vAA, field@BBBB */ 8264 movl rSELF,%ecx 8265 movzwl 2(rPC),%eax # eax<- field ref BBBB 8266 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 8267 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 8268#if defined(WITH_JIT) 8269 movl %ecx, TMP_SPILL1(%ebp) 8270 lea (%ecx,%eax,4),%ecx 8271 movl %ecx, TMP_SPILL2(%ebp) 8272 movl TMP_SPILL1(%ebp), %ecx 8273#endif 8274 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 8275 testl %eax,%eax # resolved entry null? 8276 je .LOP_SGET_OBJECT_VOLATILE_resolve # if not, make it so 8277.LOP_SGET_OBJECT_VOLATILE_finish: # field ptr in eax 8278 movl offStaticField_value(%eax),%eax 8279 FETCH_INST_OPCODE 2 %ecx 8280 ADVANCE_PC 2 8281 SET_VREG %eax rINST 8282 GOTO_NEXT_R %ecx 8283 8284 /* 8285 * Go resolve the field 8286 */ 8287.LOP_SGET_OBJECT_VOLATILE_resolve: 8288 movl rSELF,%ecx 8289 movzwl 2(rPC),%eax # eax<- field ref BBBB 8290 movl offThread_method(%ecx),%ecx # ecx<- current method 8291 EXPORT_PC # could throw, need to export 8292 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 8293 movl %eax,OUT_ARG1(%esp) 8294 movl %ecx,OUT_ARG0(%esp) 8295 SPILL(rIBASE) 8296 call dvmResolveStaticField # eax<- resolved StaticField ptr 8297 UNSPILL(rIBASE) 8298 testl %eax,%eax 8299 je common_exceptionThrown # no, handle exception 8300#if defined(WITH_JIT) 8301 movl TMP_SPILL2(%ebp), %ecx 8302 SPILL(rIBASE) 8303 call common_verifyField 8304 UNSPILL(rIBASE) 8305#endif 8306 jmp .LOP_SGET_OBJECT_VOLATILE_finish # success, continue 8307 8308 8309/* ------------------------------ */ 8310.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 8311/* File: x86/OP_SPUT_OBJECT_VOLATILE.S */ 8312/* File: x86/OP_SPUT_OBJECT.S */ 8313 /* 8314 * SPUT object handler. 8315 */ 8316 /* op vAA, field@BBBB */ 8317 movl rSELF,%ecx 8318 movzwl 2(rPC),%eax # eax<- field ref BBBB 8319 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 8320 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 8321#if defined(WITH_JIT) 8322 movl %ecx, TMP_SPILL1(%ebp) 8323 lea (%ecx,%eax,4),%ecx 8324 movl %ecx, TMP_SPILL2(%ebp) 8325 movl TMP_SPILL1(%ebp), %ecx 8326#endif 8327 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField 8328 testl %eax,%eax # resolved entry null? 8329 je .LOP_SPUT_OBJECT_VOLATILE_resolve # if not, make it so 8330.LOP_SPUT_OBJECT_VOLATILE_finish: # field ptr in eax 8331 movzbl rINSTbl,%ecx # ecx<- AA 8332 GET_VREG_R %ecx %ecx 8333 movl %ecx,offStaticField_value(%eax) # do the store 8334 testl %ecx,%ecx # stored null object ptr? 8335 je 1f # skip card mark if null 8336 movl rSELF,%ecx 8337 movl offField_clazz(%eax),%eax # eax<- method->clazz 8338 movl offThread_cardTable(%ecx),%ecx # get card table base 8339 shrl $GC_CARD_SHIFT,%eax # head to card number 8340 movb %cl,(%ecx,%eax) # mark card 83411: 8342 FETCH_INST_OPCODE 2 %ecx 8343 ADVANCE_PC 2 8344 GOTO_NEXT_R %ecx 8345 8346.LOP_SPUT_OBJECT_VOLATILE_resolve: 8347 movl rSELF,%ecx 8348 movzwl 2(rPC),%eax # eax<- field ref BBBB 8349 movl offThread_method(%ecx),%ecx # ecx<- current method 8350 EXPORT_PC # could throw, need to export 8351 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 8352 movl %eax,OUT_ARG1(%esp) 8353 movl %ecx,OUT_ARG0(%esp) 8354 SPILL(rIBASE) 8355 call dvmResolveStaticField # eax<- resolved StaticField ptr 8356 UNSPILL(rIBASE) 8357 testl %eax,%eax 8358 je common_exceptionThrown # no, handle exception 8359#if defined(WITH_JIT) 8360 movl TMP_SPILL2(%ebp), %ecx 8361 SPILL(rIBASE) 8362 call common_verifyField 8363 UNSPILL(rIBASE) 8364#endif 8365 jmp .LOP_SPUT_OBJECT_VOLATILE_finish # success, continue 8366 8367 8368/* ------------------------------ */ 8369.L_OP_UNUSED_FF: /* 0xff */ 8370/* File: x86/OP_UNUSED_FF.S */ 8371/* File: x86/unused.S */ 8372 jmp common_abort 8373 8374 8375 .size dvmAsmInstructionStartCode, .-dvmAsmInstructionStartCode 8376 .global dvmAsmInstructionEndCode 8377dvmAsmInstructionEndCode: 8378 8379 .global dvmAsmAltInstructionStartCode 8380 .type dvmAsmAltInstructionStartCode, %function 8381 .text 8382 8383dvmAsmAltInstructionStartCode = .L_ALT_OP_NOP 8384/* ------------------------------ */ 8385.L_ALT_OP_NOP: /* 0x00 */ 8386/* File: x86/alt_stub.S */ 8387/* 8388 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8389 * any interesting requests and then jump to the real instruction 8390 * handler. Unlike the Arm handler, we can't do this as a tail call 8391 * because rIBASE is caller save and we need to reload it. 8392 * 8393 * Note that unlike in the Arm implementation, we should never arrive 8394 * here with a zero breakFlag because we always refresh rIBASE on 8395 * return. 8396 */ 8397 EXPORT_PC 8398 movl rSELF, %eax 8399 movl rPC, OUT_ARG0(%esp) 8400 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8401 movl rFP, OUT_ARG1(%esp) 8402 je 1f # reload rIBASE & resume if not 8403 movl %eax, OUT_ARG2(%esp) 8404 call dvmCheckBefore # (dPC, dFP, self) 8405 movl rSELF, %eax 84061: 8407 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8408 jmp *dvmAsmInstructionStart+(0*4) 8409 8410/* ------------------------------ */ 8411.L_ALT_OP_MOVE: /* 0x01 */ 8412/* File: x86/alt_stub.S */ 8413/* 8414 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8415 * any interesting requests and then jump to the real instruction 8416 * handler. Unlike the Arm handler, we can't do this as a tail call 8417 * because rIBASE is caller save and we need to reload it. 8418 * 8419 * Note that unlike in the Arm implementation, we should never arrive 8420 * here with a zero breakFlag because we always refresh rIBASE on 8421 * return. 8422 */ 8423 EXPORT_PC 8424 movl rSELF, %eax 8425 movl rPC, OUT_ARG0(%esp) 8426 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8427 movl rFP, OUT_ARG1(%esp) 8428 je 1f # reload rIBASE & resume if not 8429 movl %eax, OUT_ARG2(%esp) 8430 call dvmCheckBefore # (dPC, dFP, self) 8431 movl rSELF, %eax 84321: 8433 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8434 jmp *dvmAsmInstructionStart+(1*4) 8435 8436/* ------------------------------ */ 8437.L_ALT_OP_MOVE_FROM16: /* 0x02 */ 8438/* File: x86/alt_stub.S */ 8439/* 8440 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8441 * any interesting requests and then jump to the real instruction 8442 * handler. Unlike the Arm handler, we can't do this as a tail call 8443 * because rIBASE is caller save and we need to reload it. 8444 * 8445 * Note that unlike in the Arm implementation, we should never arrive 8446 * here with a zero breakFlag because we always refresh rIBASE on 8447 * return. 8448 */ 8449 EXPORT_PC 8450 movl rSELF, %eax 8451 movl rPC, OUT_ARG0(%esp) 8452 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8453 movl rFP, OUT_ARG1(%esp) 8454 je 1f # reload rIBASE & resume if not 8455 movl %eax, OUT_ARG2(%esp) 8456 call dvmCheckBefore # (dPC, dFP, self) 8457 movl rSELF, %eax 84581: 8459 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8460 jmp *dvmAsmInstructionStart+(2*4) 8461 8462/* ------------------------------ */ 8463.L_ALT_OP_MOVE_16: /* 0x03 */ 8464/* File: x86/alt_stub.S */ 8465/* 8466 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8467 * any interesting requests and then jump to the real instruction 8468 * handler. Unlike the Arm handler, we can't do this as a tail call 8469 * because rIBASE is caller save and we need to reload it. 8470 * 8471 * Note that unlike in the Arm implementation, we should never arrive 8472 * here with a zero breakFlag because we always refresh rIBASE on 8473 * return. 8474 */ 8475 EXPORT_PC 8476 movl rSELF, %eax 8477 movl rPC, OUT_ARG0(%esp) 8478 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8479 movl rFP, OUT_ARG1(%esp) 8480 je 1f # reload rIBASE & resume if not 8481 movl %eax, OUT_ARG2(%esp) 8482 call dvmCheckBefore # (dPC, dFP, self) 8483 movl rSELF, %eax 84841: 8485 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8486 jmp *dvmAsmInstructionStart+(3*4) 8487 8488/* ------------------------------ */ 8489.L_ALT_OP_MOVE_WIDE: /* 0x04 */ 8490/* File: x86/alt_stub.S */ 8491/* 8492 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8493 * any interesting requests and then jump to the real instruction 8494 * handler. Unlike the Arm handler, we can't do this as a tail call 8495 * because rIBASE is caller save and we need to reload it. 8496 * 8497 * Note that unlike in the Arm implementation, we should never arrive 8498 * here with a zero breakFlag because we always refresh rIBASE on 8499 * return. 8500 */ 8501 EXPORT_PC 8502 movl rSELF, %eax 8503 movl rPC, OUT_ARG0(%esp) 8504 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8505 movl rFP, OUT_ARG1(%esp) 8506 je 1f # reload rIBASE & resume if not 8507 movl %eax, OUT_ARG2(%esp) 8508 call dvmCheckBefore # (dPC, dFP, self) 8509 movl rSELF, %eax 85101: 8511 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8512 jmp *dvmAsmInstructionStart+(4*4) 8513 8514/* ------------------------------ */ 8515.L_ALT_OP_MOVE_WIDE_FROM16: /* 0x05 */ 8516/* File: x86/alt_stub.S */ 8517/* 8518 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8519 * any interesting requests and then jump to the real instruction 8520 * handler. Unlike the Arm handler, we can't do this as a tail call 8521 * because rIBASE is caller save and we need to reload it. 8522 * 8523 * Note that unlike in the Arm implementation, we should never arrive 8524 * here with a zero breakFlag because we always refresh rIBASE on 8525 * return. 8526 */ 8527 EXPORT_PC 8528 movl rSELF, %eax 8529 movl rPC, OUT_ARG0(%esp) 8530 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8531 movl rFP, OUT_ARG1(%esp) 8532 je 1f # reload rIBASE & resume if not 8533 movl %eax, OUT_ARG2(%esp) 8534 call dvmCheckBefore # (dPC, dFP, self) 8535 movl rSELF, %eax 85361: 8537 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8538 jmp *dvmAsmInstructionStart+(5*4) 8539 8540/* ------------------------------ */ 8541.L_ALT_OP_MOVE_WIDE_16: /* 0x06 */ 8542/* File: x86/alt_stub.S */ 8543/* 8544 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8545 * any interesting requests and then jump to the real instruction 8546 * handler. Unlike the Arm handler, we can't do this as a tail call 8547 * because rIBASE is caller save and we need to reload it. 8548 * 8549 * Note that unlike in the Arm implementation, we should never arrive 8550 * here with a zero breakFlag because we always refresh rIBASE on 8551 * return. 8552 */ 8553 EXPORT_PC 8554 movl rSELF, %eax 8555 movl rPC, OUT_ARG0(%esp) 8556 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8557 movl rFP, OUT_ARG1(%esp) 8558 je 1f # reload rIBASE & resume if not 8559 movl %eax, OUT_ARG2(%esp) 8560 call dvmCheckBefore # (dPC, dFP, self) 8561 movl rSELF, %eax 85621: 8563 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8564 jmp *dvmAsmInstructionStart+(6*4) 8565 8566/* ------------------------------ */ 8567.L_ALT_OP_MOVE_OBJECT: /* 0x07 */ 8568/* File: x86/alt_stub.S */ 8569/* 8570 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8571 * any interesting requests and then jump to the real instruction 8572 * handler. Unlike the Arm handler, we can't do this as a tail call 8573 * because rIBASE is caller save and we need to reload it. 8574 * 8575 * Note that unlike in the Arm implementation, we should never arrive 8576 * here with a zero breakFlag because we always refresh rIBASE on 8577 * return. 8578 */ 8579 EXPORT_PC 8580 movl rSELF, %eax 8581 movl rPC, OUT_ARG0(%esp) 8582 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8583 movl rFP, OUT_ARG1(%esp) 8584 je 1f # reload rIBASE & resume if not 8585 movl %eax, OUT_ARG2(%esp) 8586 call dvmCheckBefore # (dPC, dFP, self) 8587 movl rSELF, %eax 85881: 8589 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8590 jmp *dvmAsmInstructionStart+(7*4) 8591 8592/* ------------------------------ */ 8593.L_ALT_OP_MOVE_OBJECT_FROM16: /* 0x08 */ 8594/* File: x86/alt_stub.S */ 8595/* 8596 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8597 * any interesting requests and then jump to the real instruction 8598 * handler. Unlike the Arm handler, we can't do this as a tail call 8599 * because rIBASE is caller save and we need to reload it. 8600 * 8601 * Note that unlike in the Arm implementation, we should never arrive 8602 * here with a zero breakFlag because we always refresh rIBASE on 8603 * return. 8604 */ 8605 EXPORT_PC 8606 movl rSELF, %eax 8607 movl rPC, OUT_ARG0(%esp) 8608 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8609 movl rFP, OUT_ARG1(%esp) 8610 je 1f # reload rIBASE & resume if not 8611 movl %eax, OUT_ARG2(%esp) 8612 call dvmCheckBefore # (dPC, dFP, self) 8613 movl rSELF, %eax 86141: 8615 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8616 jmp *dvmAsmInstructionStart+(8*4) 8617 8618/* ------------------------------ */ 8619.L_ALT_OP_MOVE_OBJECT_16: /* 0x09 */ 8620/* File: x86/alt_stub.S */ 8621/* 8622 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8623 * any interesting requests and then jump to the real instruction 8624 * handler. Unlike the Arm handler, we can't do this as a tail call 8625 * because rIBASE is caller save and we need to reload it. 8626 * 8627 * Note that unlike in the Arm implementation, we should never arrive 8628 * here with a zero breakFlag because we always refresh rIBASE on 8629 * return. 8630 */ 8631 EXPORT_PC 8632 movl rSELF, %eax 8633 movl rPC, OUT_ARG0(%esp) 8634 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8635 movl rFP, OUT_ARG1(%esp) 8636 je 1f # reload rIBASE & resume if not 8637 movl %eax, OUT_ARG2(%esp) 8638 call dvmCheckBefore # (dPC, dFP, self) 8639 movl rSELF, %eax 86401: 8641 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8642 jmp *dvmAsmInstructionStart+(9*4) 8643 8644/* ------------------------------ */ 8645.L_ALT_OP_MOVE_RESULT: /* 0x0a */ 8646/* File: x86/alt_stub.S */ 8647/* 8648 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8649 * any interesting requests and then jump to the real instruction 8650 * handler. Unlike the Arm handler, we can't do this as a tail call 8651 * because rIBASE is caller save and we need to reload it. 8652 * 8653 * Note that unlike in the Arm implementation, we should never arrive 8654 * here with a zero breakFlag because we always refresh rIBASE on 8655 * return. 8656 */ 8657 EXPORT_PC 8658 movl rSELF, %eax 8659 movl rPC, OUT_ARG0(%esp) 8660 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8661 movl rFP, OUT_ARG1(%esp) 8662 je 1f # reload rIBASE & resume if not 8663 movl %eax, OUT_ARG2(%esp) 8664 call dvmCheckBefore # (dPC, dFP, self) 8665 movl rSELF, %eax 86661: 8667 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8668 jmp *dvmAsmInstructionStart+(10*4) 8669 8670/* ------------------------------ */ 8671.L_ALT_OP_MOVE_RESULT_WIDE: /* 0x0b */ 8672/* File: x86/alt_stub.S */ 8673/* 8674 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8675 * any interesting requests and then jump to the real instruction 8676 * handler. Unlike the Arm handler, we can't do this as a tail call 8677 * because rIBASE is caller save and we need to reload it. 8678 * 8679 * Note that unlike in the Arm implementation, we should never arrive 8680 * here with a zero breakFlag because we always refresh rIBASE on 8681 * return. 8682 */ 8683 EXPORT_PC 8684 movl rSELF, %eax 8685 movl rPC, OUT_ARG0(%esp) 8686 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8687 movl rFP, OUT_ARG1(%esp) 8688 je 1f # reload rIBASE & resume if not 8689 movl %eax, OUT_ARG2(%esp) 8690 call dvmCheckBefore # (dPC, dFP, self) 8691 movl rSELF, %eax 86921: 8693 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8694 jmp *dvmAsmInstructionStart+(11*4) 8695 8696/* ------------------------------ */ 8697.L_ALT_OP_MOVE_RESULT_OBJECT: /* 0x0c */ 8698/* File: x86/alt_stub.S */ 8699/* 8700 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8701 * any interesting requests and then jump to the real instruction 8702 * handler. Unlike the Arm handler, we can't do this as a tail call 8703 * because rIBASE is caller save and we need to reload it. 8704 * 8705 * Note that unlike in the Arm implementation, we should never arrive 8706 * here with a zero breakFlag because we always refresh rIBASE on 8707 * return. 8708 */ 8709 EXPORT_PC 8710 movl rSELF, %eax 8711 movl rPC, OUT_ARG0(%esp) 8712 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8713 movl rFP, OUT_ARG1(%esp) 8714 je 1f # reload rIBASE & resume if not 8715 movl %eax, OUT_ARG2(%esp) 8716 call dvmCheckBefore # (dPC, dFP, self) 8717 movl rSELF, %eax 87181: 8719 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8720 jmp *dvmAsmInstructionStart+(12*4) 8721 8722/* ------------------------------ */ 8723.L_ALT_OP_MOVE_EXCEPTION: /* 0x0d */ 8724/* File: x86/alt_stub.S */ 8725/* 8726 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8727 * any interesting requests and then jump to the real instruction 8728 * handler. Unlike the Arm handler, we can't do this as a tail call 8729 * because rIBASE is caller save and we need to reload it. 8730 * 8731 * Note that unlike in the Arm implementation, we should never arrive 8732 * here with a zero breakFlag because we always refresh rIBASE on 8733 * return. 8734 */ 8735 EXPORT_PC 8736 movl rSELF, %eax 8737 movl rPC, OUT_ARG0(%esp) 8738 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8739 movl rFP, OUT_ARG1(%esp) 8740 je 1f # reload rIBASE & resume if not 8741 movl %eax, OUT_ARG2(%esp) 8742 call dvmCheckBefore # (dPC, dFP, self) 8743 movl rSELF, %eax 87441: 8745 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8746 jmp *dvmAsmInstructionStart+(13*4) 8747 8748/* ------------------------------ */ 8749.L_ALT_OP_RETURN_VOID: /* 0x0e */ 8750/* File: x86/alt_stub.S */ 8751/* 8752 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8753 * any interesting requests and then jump to the real instruction 8754 * handler. Unlike the Arm handler, we can't do this as a tail call 8755 * because rIBASE is caller save and we need to reload it. 8756 * 8757 * Note that unlike in the Arm implementation, we should never arrive 8758 * here with a zero breakFlag because we always refresh rIBASE on 8759 * return. 8760 */ 8761 EXPORT_PC 8762 movl rSELF, %eax 8763 movl rPC, OUT_ARG0(%esp) 8764 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8765 movl rFP, OUT_ARG1(%esp) 8766 je 1f # reload rIBASE & resume if not 8767 movl %eax, OUT_ARG2(%esp) 8768 call dvmCheckBefore # (dPC, dFP, self) 8769 movl rSELF, %eax 87701: 8771 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8772 jmp *dvmAsmInstructionStart+(14*4) 8773 8774/* ------------------------------ */ 8775.L_ALT_OP_RETURN: /* 0x0f */ 8776/* File: x86/alt_stub.S */ 8777/* 8778 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8779 * any interesting requests and then jump to the real instruction 8780 * handler. Unlike the Arm handler, we can't do this as a tail call 8781 * because rIBASE is caller save and we need to reload it. 8782 * 8783 * Note that unlike in the Arm implementation, we should never arrive 8784 * here with a zero breakFlag because we always refresh rIBASE on 8785 * return. 8786 */ 8787 EXPORT_PC 8788 movl rSELF, %eax 8789 movl rPC, OUT_ARG0(%esp) 8790 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8791 movl rFP, OUT_ARG1(%esp) 8792 je 1f # reload rIBASE & resume if not 8793 movl %eax, OUT_ARG2(%esp) 8794 call dvmCheckBefore # (dPC, dFP, self) 8795 movl rSELF, %eax 87961: 8797 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8798 jmp *dvmAsmInstructionStart+(15*4) 8799 8800/* ------------------------------ */ 8801.L_ALT_OP_RETURN_WIDE: /* 0x10 */ 8802/* File: x86/alt_stub.S */ 8803/* 8804 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8805 * any interesting requests and then jump to the real instruction 8806 * handler. Unlike the Arm handler, we can't do this as a tail call 8807 * because rIBASE is caller save and we need to reload it. 8808 * 8809 * Note that unlike in the Arm implementation, we should never arrive 8810 * here with a zero breakFlag because we always refresh rIBASE on 8811 * return. 8812 */ 8813 EXPORT_PC 8814 movl rSELF, %eax 8815 movl rPC, OUT_ARG0(%esp) 8816 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8817 movl rFP, OUT_ARG1(%esp) 8818 je 1f # reload rIBASE & resume if not 8819 movl %eax, OUT_ARG2(%esp) 8820 call dvmCheckBefore # (dPC, dFP, self) 8821 movl rSELF, %eax 88221: 8823 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8824 jmp *dvmAsmInstructionStart+(16*4) 8825 8826/* ------------------------------ */ 8827.L_ALT_OP_RETURN_OBJECT: /* 0x11 */ 8828/* File: x86/alt_stub.S */ 8829/* 8830 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8831 * any interesting requests and then jump to the real instruction 8832 * handler. Unlike the Arm handler, we can't do this as a tail call 8833 * because rIBASE is caller save and we need to reload it. 8834 * 8835 * Note that unlike in the Arm implementation, we should never arrive 8836 * here with a zero breakFlag because we always refresh rIBASE on 8837 * return. 8838 */ 8839 EXPORT_PC 8840 movl rSELF, %eax 8841 movl rPC, OUT_ARG0(%esp) 8842 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8843 movl rFP, OUT_ARG1(%esp) 8844 je 1f # reload rIBASE & resume if not 8845 movl %eax, OUT_ARG2(%esp) 8846 call dvmCheckBefore # (dPC, dFP, self) 8847 movl rSELF, %eax 88481: 8849 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8850 jmp *dvmAsmInstructionStart+(17*4) 8851 8852/* ------------------------------ */ 8853.L_ALT_OP_CONST_4: /* 0x12 */ 8854/* File: x86/alt_stub.S */ 8855/* 8856 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8857 * any interesting requests and then jump to the real instruction 8858 * handler. Unlike the Arm handler, we can't do this as a tail call 8859 * because rIBASE is caller save and we need to reload it. 8860 * 8861 * Note that unlike in the Arm implementation, we should never arrive 8862 * here with a zero breakFlag because we always refresh rIBASE on 8863 * return. 8864 */ 8865 EXPORT_PC 8866 movl rSELF, %eax 8867 movl rPC, OUT_ARG0(%esp) 8868 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8869 movl rFP, OUT_ARG1(%esp) 8870 je 1f # reload rIBASE & resume if not 8871 movl %eax, OUT_ARG2(%esp) 8872 call dvmCheckBefore # (dPC, dFP, self) 8873 movl rSELF, %eax 88741: 8875 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8876 jmp *dvmAsmInstructionStart+(18*4) 8877 8878/* ------------------------------ */ 8879.L_ALT_OP_CONST_16: /* 0x13 */ 8880/* File: x86/alt_stub.S */ 8881/* 8882 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8883 * any interesting requests and then jump to the real instruction 8884 * handler. Unlike the Arm handler, we can't do this as a tail call 8885 * because rIBASE is caller save and we need to reload it. 8886 * 8887 * Note that unlike in the Arm implementation, we should never arrive 8888 * here with a zero breakFlag because we always refresh rIBASE on 8889 * return. 8890 */ 8891 EXPORT_PC 8892 movl rSELF, %eax 8893 movl rPC, OUT_ARG0(%esp) 8894 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8895 movl rFP, OUT_ARG1(%esp) 8896 je 1f # reload rIBASE & resume if not 8897 movl %eax, OUT_ARG2(%esp) 8898 call dvmCheckBefore # (dPC, dFP, self) 8899 movl rSELF, %eax 89001: 8901 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8902 jmp *dvmAsmInstructionStart+(19*4) 8903 8904/* ------------------------------ */ 8905.L_ALT_OP_CONST: /* 0x14 */ 8906/* File: x86/alt_stub.S */ 8907/* 8908 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8909 * any interesting requests and then jump to the real instruction 8910 * handler. Unlike the Arm handler, we can't do this as a tail call 8911 * because rIBASE is caller save and we need to reload it. 8912 * 8913 * Note that unlike in the Arm implementation, we should never arrive 8914 * here with a zero breakFlag because we always refresh rIBASE on 8915 * return. 8916 */ 8917 EXPORT_PC 8918 movl rSELF, %eax 8919 movl rPC, OUT_ARG0(%esp) 8920 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8921 movl rFP, OUT_ARG1(%esp) 8922 je 1f # reload rIBASE & resume if not 8923 movl %eax, OUT_ARG2(%esp) 8924 call dvmCheckBefore # (dPC, dFP, self) 8925 movl rSELF, %eax 89261: 8927 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8928 jmp *dvmAsmInstructionStart+(20*4) 8929 8930/* ------------------------------ */ 8931.L_ALT_OP_CONST_HIGH16: /* 0x15 */ 8932/* File: x86/alt_stub.S */ 8933/* 8934 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8935 * any interesting requests and then jump to the real instruction 8936 * handler. Unlike the Arm handler, we can't do this as a tail call 8937 * because rIBASE is caller save and we need to reload it. 8938 * 8939 * Note that unlike in the Arm implementation, we should never arrive 8940 * here with a zero breakFlag because we always refresh rIBASE on 8941 * return. 8942 */ 8943 EXPORT_PC 8944 movl rSELF, %eax 8945 movl rPC, OUT_ARG0(%esp) 8946 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8947 movl rFP, OUT_ARG1(%esp) 8948 je 1f # reload rIBASE & resume if not 8949 movl %eax, OUT_ARG2(%esp) 8950 call dvmCheckBefore # (dPC, dFP, self) 8951 movl rSELF, %eax 89521: 8953 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8954 jmp *dvmAsmInstructionStart+(21*4) 8955 8956/* ------------------------------ */ 8957.L_ALT_OP_CONST_WIDE_16: /* 0x16 */ 8958/* File: x86/alt_stub.S */ 8959/* 8960 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8961 * any interesting requests and then jump to the real instruction 8962 * handler. Unlike the Arm handler, we can't do this as a tail call 8963 * because rIBASE is caller save and we need to reload it. 8964 * 8965 * Note that unlike in the Arm implementation, we should never arrive 8966 * here with a zero breakFlag because we always refresh rIBASE on 8967 * return. 8968 */ 8969 EXPORT_PC 8970 movl rSELF, %eax 8971 movl rPC, OUT_ARG0(%esp) 8972 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8973 movl rFP, OUT_ARG1(%esp) 8974 je 1f # reload rIBASE & resume if not 8975 movl %eax, OUT_ARG2(%esp) 8976 call dvmCheckBefore # (dPC, dFP, self) 8977 movl rSELF, %eax 89781: 8979 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 8980 jmp *dvmAsmInstructionStart+(22*4) 8981 8982/* ------------------------------ */ 8983.L_ALT_OP_CONST_WIDE_32: /* 0x17 */ 8984/* File: x86/alt_stub.S */ 8985/* 8986 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 8987 * any interesting requests and then jump to the real instruction 8988 * handler. Unlike the Arm handler, we can't do this as a tail call 8989 * because rIBASE is caller save and we need to reload it. 8990 * 8991 * Note that unlike in the Arm implementation, we should never arrive 8992 * here with a zero breakFlag because we always refresh rIBASE on 8993 * return. 8994 */ 8995 EXPORT_PC 8996 movl rSELF, %eax 8997 movl rPC, OUT_ARG0(%esp) 8998 cmpb $0,offThread_breakFlags(%eax) # anything to do? 8999 movl rFP, OUT_ARG1(%esp) 9000 je 1f # reload rIBASE & resume if not 9001 movl %eax, OUT_ARG2(%esp) 9002 call dvmCheckBefore # (dPC, dFP, self) 9003 movl rSELF, %eax 90041: 9005 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9006 jmp *dvmAsmInstructionStart+(23*4) 9007 9008/* ------------------------------ */ 9009.L_ALT_OP_CONST_WIDE: /* 0x18 */ 9010/* File: x86/alt_stub.S */ 9011/* 9012 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9013 * any interesting requests and then jump to the real instruction 9014 * handler. Unlike the Arm handler, we can't do this as a tail call 9015 * because rIBASE is caller save and we need to reload it. 9016 * 9017 * Note that unlike in the Arm implementation, we should never arrive 9018 * here with a zero breakFlag because we always refresh rIBASE on 9019 * return. 9020 */ 9021 EXPORT_PC 9022 movl rSELF, %eax 9023 movl rPC, OUT_ARG0(%esp) 9024 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9025 movl rFP, OUT_ARG1(%esp) 9026 je 1f # reload rIBASE & resume if not 9027 movl %eax, OUT_ARG2(%esp) 9028 call dvmCheckBefore # (dPC, dFP, self) 9029 movl rSELF, %eax 90301: 9031 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9032 jmp *dvmAsmInstructionStart+(24*4) 9033 9034/* ------------------------------ */ 9035.L_ALT_OP_CONST_WIDE_HIGH16: /* 0x19 */ 9036/* File: x86/alt_stub.S */ 9037/* 9038 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9039 * any interesting requests and then jump to the real instruction 9040 * handler. Unlike the Arm handler, we can't do this as a tail call 9041 * because rIBASE is caller save and we need to reload it. 9042 * 9043 * Note that unlike in the Arm implementation, we should never arrive 9044 * here with a zero breakFlag because we always refresh rIBASE on 9045 * return. 9046 */ 9047 EXPORT_PC 9048 movl rSELF, %eax 9049 movl rPC, OUT_ARG0(%esp) 9050 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9051 movl rFP, OUT_ARG1(%esp) 9052 je 1f # reload rIBASE & resume if not 9053 movl %eax, OUT_ARG2(%esp) 9054 call dvmCheckBefore # (dPC, dFP, self) 9055 movl rSELF, %eax 90561: 9057 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9058 jmp *dvmAsmInstructionStart+(25*4) 9059 9060/* ------------------------------ */ 9061.L_ALT_OP_CONST_STRING: /* 0x1a */ 9062/* File: x86/alt_stub.S */ 9063/* 9064 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9065 * any interesting requests and then jump to the real instruction 9066 * handler. Unlike the Arm handler, we can't do this as a tail call 9067 * because rIBASE is caller save and we need to reload it. 9068 * 9069 * Note that unlike in the Arm implementation, we should never arrive 9070 * here with a zero breakFlag because we always refresh rIBASE on 9071 * return. 9072 */ 9073 EXPORT_PC 9074 movl rSELF, %eax 9075 movl rPC, OUT_ARG0(%esp) 9076 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9077 movl rFP, OUT_ARG1(%esp) 9078 je 1f # reload rIBASE & resume if not 9079 movl %eax, OUT_ARG2(%esp) 9080 call dvmCheckBefore # (dPC, dFP, self) 9081 movl rSELF, %eax 90821: 9083 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9084 jmp *dvmAsmInstructionStart+(26*4) 9085 9086/* ------------------------------ */ 9087.L_ALT_OP_CONST_STRING_JUMBO: /* 0x1b */ 9088/* File: x86/alt_stub.S */ 9089/* 9090 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9091 * any interesting requests and then jump to the real instruction 9092 * handler. Unlike the Arm handler, we can't do this as a tail call 9093 * because rIBASE is caller save and we need to reload it. 9094 * 9095 * Note that unlike in the Arm implementation, we should never arrive 9096 * here with a zero breakFlag because we always refresh rIBASE on 9097 * return. 9098 */ 9099 EXPORT_PC 9100 movl rSELF, %eax 9101 movl rPC, OUT_ARG0(%esp) 9102 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9103 movl rFP, OUT_ARG1(%esp) 9104 je 1f # reload rIBASE & resume if not 9105 movl %eax, OUT_ARG2(%esp) 9106 call dvmCheckBefore # (dPC, dFP, self) 9107 movl rSELF, %eax 91081: 9109 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9110 jmp *dvmAsmInstructionStart+(27*4) 9111 9112/* ------------------------------ */ 9113.L_ALT_OP_CONST_CLASS: /* 0x1c */ 9114/* File: x86/alt_stub.S */ 9115/* 9116 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9117 * any interesting requests and then jump to the real instruction 9118 * handler. Unlike the Arm handler, we can't do this as a tail call 9119 * because rIBASE is caller save and we need to reload it. 9120 * 9121 * Note that unlike in the Arm implementation, we should never arrive 9122 * here with a zero breakFlag because we always refresh rIBASE on 9123 * return. 9124 */ 9125 EXPORT_PC 9126 movl rSELF, %eax 9127 movl rPC, OUT_ARG0(%esp) 9128 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9129 movl rFP, OUT_ARG1(%esp) 9130 je 1f # reload rIBASE & resume if not 9131 movl %eax, OUT_ARG2(%esp) 9132 call dvmCheckBefore # (dPC, dFP, self) 9133 movl rSELF, %eax 91341: 9135 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9136 jmp *dvmAsmInstructionStart+(28*4) 9137 9138/* ------------------------------ */ 9139.L_ALT_OP_MONITOR_ENTER: /* 0x1d */ 9140/* File: x86/alt_stub.S */ 9141/* 9142 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9143 * any interesting requests and then jump to the real instruction 9144 * handler. Unlike the Arm handler, we can't do this as a tail call 9145 * because rIBASE is caller save and we need to reload it. 9146 * 9147 * Note that unlike in the Arm implementation, we should never arrive 9148 * here with a zero breakFlag because we always refresh rIBASE on 9149 * return. 9150 */ 9151 EXPORT_PC 9152 movl rSELF, %eax 9153 movl rPC, OUT_ARG0(%esp) 9154 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9155 movl rFP, OUT_ARG1(%esp) 9156 je 1f # reload rIBASE & resume if not 9157 movl %eax, OUT_ARG2(%esp) 9158 call dvmCheckBefore # (dPC, dFP, self) 9159 movl rSELF, %eax 91601: 9161 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9162 jmp *dvmAsmInstructionStart+(29*4) 9163 9164/* ------------------------------ */ 9165.L_ALT_OP_MONITOR_EXIT: /* 0x1e */ 9166/* File: x86/alt_stub.S */ 9167/* 9168 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9169 * any interesting requests and then jump to the real instruction 9170 * handler. Unlike the Arm handler, we can't do this as a tail call 9171 * because rIBASE is caller save and we need to reload it. 9172 * 9173 * Note that unlike in the Arm implementation, we should never arrive 9174 * here with a zero breakFlag because we always refresh rIBASE on 9175 * return. 9176 */ 9177 EXPORT_PC 9178 movl rSELF, %eax 9179 movl rPC, OUT_ARG0(%esp) 9180 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9181 movl rFP, OUT_ARG1(%esp) 9182 je 1f # reload rIBASE & resume if not 9183 movl %eax, OUT_ARG2(%esp) 9184 call dvmCheckBefore # (dPC, dFP, self) 9185 movl rSELF, %eax 91861: 9187 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9188 jmp *dvmAsmInstructionStart+(30*4) 9189 9190/* ------------------------------ */ 9191.L_ALT_OP_CHECK_CAST: /* 0x1f */ 9192/* File: x86/alt_stub.S */ 9193/* 9194 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9195 * any interesting requests and then jump to the real instruction 9196 * handler. Unlike the Arm handler, we can't do this as a tail call 9197 * because rIBASE is caller save and we need to reload it. 9198 * 9199 * Note that unlike in the Arm implementation, we should never arrive 9200 * here with a zero breakFlag because we always refresh rIBASE on 9201 * return. 9202 */ 9203 EXPORT_PC 9204 movl rSELF, %eax 9205 movl rPC, OUT_ARG0(%esp) 9206 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9207 movl rFP, OUT_ARG1(%esp) 9208 je 1f # reload rIBASE & resume if not 9209 movl %eax, OUT_ARG2(%esp) 9210 call dvmCheckBefore # (dPC, dFP, self) 9211 movl rSELF, %eax 92121: 9213 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9214 jmp *dvmAsmInstructionStart+(31*4) 9215 9216/* ------------------------------ */ 9217.L_ALT_OP_INSTANCE_OF: /* 0x20 */ 9218/* File: x86/alt_stub.S */ 9219/* 9220 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9221 * any interesting requests and then jump to the real instruction 9222 * handler. Unlike the Arm handler, we can't do this as a tail call 9223 * because rIBASE is caller save and we need to reload it. 9224 * 9225 * Note that unlike in the Arm implementation, we should never arrive 9226 * here with a zero breakFlag because we always refresh rIBASE on 9227 * return. 9228 */ 9229 EXPORT_PC 9230 movl rSELF, %eax 9231 movl rPC, OUT_ARG0(%esp) 9232 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9233 movl rFP, OUT_ARG1(%esp) 9234 je 1f # reload rIBASE & resume if not 9235 movl %eax, OUT_ARG2(%esp) 9236 call dvmCheckBefore # (dPC, dFP, self) 9237 movl rSELF, %eax 92381: 9239 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9240 jmp *dvmAsmInstructionStart+(32*4) 9241 9242/* ------------------------------ */ 9243.L_ALT_OP_ARRAY_LENGTH: /* 0x21 */ 9244/* File: x86/alt_stub.S */ 9245/* 9246 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9247 * any interesting requests and then jump to the real instruction 9248 * handler. Unlike the Arm handler, we can't do this as a tail call 9249 * because rIBASE is caller save and we need to reload it. 9250 * 9251 * Note that unlike in the Arm implementation, we should never arrive 9252 * here with a zero breakFlag because we always refresh rIBASE on 9253 * return. 9254 */ 9255 EXPORT_PC 9256 movl rSELF, %eax 9257 movl rPC, OUT_ARG0(%esp) 9258 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9259 movl rFP, OUT_ARG1(%esp) 9260 je 1f # reload rIBASE & resume if not 9261 movl %eax, OUT_ARG2(%esp) 9262 call dvmCheckBefore # (dPC, dFP, self) 9263 movl rSELF, %eax 92641: 9265 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9266 jmp *dvmAsmInstructionStart+(33*4) 9267 9268/* ------------------------------ */ 9269.L_ALT_OP_NEW_INSTANCE: /* 0x22 */ 9270/* File: x86/alt_stub.S */ 9271/* 9272 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9273 * any interesting requests and then jump to the real instruction 9274 * handler. Unlike the Arm handler, we can't do this as a tail call 9275 * because rIBASE is caller save and we need to reload it. 9276 * 9277 * Note that unlike in the Arm implementation, we should never arrive 9278 * here with a zero breakFlag because we always refresh rIBASE on 9279 * return. 9280 */ 9281 EXPORT_PC 9282 movl rSELF, %eax 9283 movl rPC, OUT_ARG0(%esp) 9284 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9285 movl rFP, OUT_ARG1(%esp) 9286 je 1f # reload rIBASE & resume if not 9287 movl %eax, OUT_ARG2(%esp) 9288 call dvmCheckBefore # (dPC, dFP, self) 9289 movl rSELF, %eax 92901: 9291 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9292 jmp *dvmAsmInstructionStart+(34*4) 9293 9294/* ------------------------------ */ 9295.L_ALT_OP_NEW_ARRAY: /* 0x23 */ 9296/* File: x86/alt_stub.S */ 9297/* 9298 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9299 * any interesting requests and then jump to the real instruction 9300 * handler. Unlike the Arm handler, we can't do this as a tail call 9301 * because rIBASE is caller save and we need to reload it. 9302 * 9303 * Note that unlike in the Arm implementation, we should never arrive 9304 * here with a zero breakFlag because we always refresh rIBASE on 9305 * return. 9306 */ 9307 EXPORT_PC 9308 movl rSELF, %eax 9309 movl rPC, OUT_ARG0(%esp) 9310 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9311 movl rFP, OUT_ARG1(%esp) 9312 je 1f # reload rIBASE & resume if not 9313 movl %eax, OUT_ARG2(%esp) 9314 call dvmCheckBefore # (dPC, dFP, self) 9315 movl rSELF, %eax 93161: 9317 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9318 jmp *dvmAsmInstructionStart+(35*4) 9319 9320/* ------------------------------ */ 9321.L_ALT_OP_FILLED_NEW_ARRAY: /* 0x24 */ 9322/* File: x86/alt_stub.S */ 9323/* 9324 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9325 * any interesting requests and then jump to the real instruction 9326 * handler. Unlike the Arm handler, we can't do this as a tail call 9327 * because rIBASE is caller save and we need to reload it. 9328 * 9329 * Note that unlike in the Arm implementation, we should never arrive 9330 * here with a zero breakFlag because we always refresh rIBASE on 9331 * return. 9332 */ 9333 EXPORT_PC 9334 movl rSELF, %eax 9335 movl rPC, OUT_ARG0(%esp) 9336 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9337 movl rFP, OUT_ARG1(%esp) 9338 je 1f # reload rIBASE & resume if not 9339 movl %eax, OUT_ARG2(%esp) 9340 call dvmCheckBefore # (dPC, dFP, self) 9341 movl rSELF, %eax 93421: 9343 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9344 jmp *dvmAsmInstructionStart+(36*4) 9345 9346/* ------------------------------ */ 9347.L_ALT_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 9348/* File: x86/alt_stub.S */ 9349/* 9350 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9351 * any interesting requests and then jump to the real instruction 9352 * handler. Unlike the Arm handler, we can't do this as a tail call 9353 * because rIBASE is caller save and we need to reload it. 9354 * 9355 * Note that unlike in the Arm implementation, we should never arrive 9356 * here with a zero breakFlag because we always refresh rIBASE on 9357 * return. 9358 */ 9359 EXPORT_PC 9360 movl rSELF, %eax 9361 movl rPC, OUT_ARG0(%esp) 9362 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9363 movl rFP, OUT_ARG1(%esp) 9364 je 1f # reload rIBASE & resume if not 9365 movl %eax, OUT_ARG2(%esp) 9366 call dvmCheckBefore # (dPC, dFP, self) 9367 movl rSELF, %eax 93681: 9369 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9370 jmp *dvmAsmInstructionStart+(37*4) 9371 9372/* ------------------------------ */ 9373.L_ALT_OP_FILL_ARRAY_DATA: /* 0x26 */ 9374/* File: x86/alt_stub.S */ 9375/* 9376 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9377 * any interesting requests and then jump to the real instruction 9378 * handler. Unlike the Arm handler, we can't do this as a tail call 9379 * because rIBASE is caller save and we need to reload it. 9380 * 9381 * Note that unlike in the Arm implementation, we should never arrive 9382 * here with a zero breakFlag because we always refresh rIBASE on 9383 * return. 9384 */ 9385 EXPORT_PC 9386 movl rSELF, %eax 9387 movl rPC, OUT_ARG0(%esp) 9388 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9389 movl rFP, OUT_ARG1(%esp) 9390 je 1f # reload rIBASE & resume if not 9391 movl %eax, OUT_ARG2(%esp) 9392 call dvmCheckBefore # (dPC, dFP, self) 9393 movl rSELF, %eax 93941: 9395 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9396 jmp *dvmAsmInstructionStart+(38*4) 9397 9398/* ------------------------------ */ 9399.L_ALT_OP_THROW: /* 0x27 */ 9400/* File: x86/alt_stub.S */ 9401/* 9402 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9403 * any interesting requests and then jump to the real instruction 9404 * handler. Unlike the Arm handler, we can't do this as a tail call 9405 * because rIBASE is caller save and we need to reload it. 9406 * 9407 * Note that unlike in the Arm implementation, we should never arrive 9408 * here with a zero breakFlag because we always refresh rIBASE on 9409 * return. 9410 */ 9411 EXPORT_PC 9412 movl rSELF, %eax 9413 movl rPC, OUT_ARG0(%esp) 9414 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9415 movl rFP, OUT_ARG1(%esp) 9416 je 1f # reload rIBASE & resume if not 9417 movl %eax, OUT_ARG2(%esp) 9418 call dvmCheckBefore # (dPC, dFP, self) 9419 movl rSELF, %eax 94201: 9421 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9422 jmp *dvmAsmInstructionStart+(39*4) 9423 9424/* ------------------------------ */ 9425.L_ALT_OP_GOTO: /* 0x28 */ 9426/* File: x86/alt_stub.S */ 9427/* 9428 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9429 * any interesting requests and then jump to the real instruction 9430 * handler. Unlike the Arm handler, we can't do this as a tail call 9431 * because rIBASE is caller save and we need to reload it. 9432 * 9433 * Note that unlike in the Arm implementation, we should never arrive 9434 * here with a zero breakFlag because we always refresh rIBASE on 9435 * return. 9436 */ 9437 EXPORT_PC 9438 movl rSELF, %eax 9439 movl rPC, OUT_ARG0(%esp) 9440 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9441 movl rFP, OUT_ARG1(%esp) 9442 je 1f # reload rIBASE & resume if not 9443 movl %eax, OUT_ARG2(%esp) 9444 call dvmCheckBefore # (dPC, dFP, self) 9445 movl rSELF, %eax 94461: 9447 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9448 jmp *dvmAsmInstructionStart+(40*4) 9449 9450/* ------------------------------ */ 9451.L_ALT_OP_GOTO_16: /* 0x29 */ 9452/* File: x86/alt_stub.S */ 9453/* 9454 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9455 * any interesting requests and then jump to the real instruction 9456 * handler. Unlike the Arm handler, we can't do this as a tail call 9457 * because rIBASE is caller save and we need to reload it. 9458 * 9459 * Note that unlike in the Arm implementation, we should never arrive 9460 * here with a zero breakFlag because we always refresh rIBASE on 9461 * return. 9462 */ 9463 EXPORT_PC 9464 movl rSELF, %eax 9465 movl rPC, OUT_ARG0(%esp) 9466 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9467 movl rFP, OUT_ARG1(%esp) 9468 je 1f # reload rIBASE & resume if not 9469 movl %eax, OUT_ARG2(%esp) 9470 call dvmCheckBefore # (dPC, dFP, self) 9471 movl rSELF, %eax 94721: 9473 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9474 jmp *dvmAsmInstructionStart+(41*4) 9475 9476/* ------------------------------ */ 9477.L_ALT_OP_GOTO_32: /* 0x2a */ 9478/* File: x86/alt_stub.S */ 9479/* 9480 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9481 * any interesting requests and then jump to the real instruction 9482 * handler. Unlike the Arm handler, we can't do this as a tail call 9483 * because rIBASE is caller save and we need to reload it. 9484 * 9485 * Note that unlike in the Arm implementation, we should never arrive 9486 * here with a zero breakFlag because we always refresh rIBASE on 9487 * return. 9488 */ 9489 EXPORT_PC 9490 movl rSELF, %eax 9491 movl rPC, OUT_ARG0(%esp) 9492 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9493 movl rFP, OUT_ARG1(%esp) 9494 je 1f # reload rIBASE & resume if not 9495 movl %eax, OUT_ARG2(%esp) 9496 call dvmCheckBefore # (dPC, dFP, self) 9497 movl rSELF, %eax 94981: 9499 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9500 jmp *dvmAsmInstructionStart+(42*4) 9501 9502/* ------------------------------ */ 9503.L_ALT_OP_PACKED_SWITCH: /* 0x2b */ 9504/* File: x86/alt_stub.S */ 9505/* 9506 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9507 * any interesting requests and then jump to the real instruction 9508 * handler. Unlike the Arm handler, we can't do this as a tail call 9509 * because rIBASE is caller save and we need to reload it. 9510 * 9511 * Note that unlike in the Arm implementation, we should never arrive 9512 * here with a zero breakFlag because we always refresh rIBASE on 9513 * return. 9514 */ 9515 EXPORT_PC 9516 movl rSELF, %eax 9517 movl rPC, OUT_ARG0(%esp) 9518 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9519 movl rFP, OUT_ARG1(%esp) 9520 je 1f # reload rIBASE & resume if not 9521 movl %eax, OUT_ARG2(%esp) 9522 call dvmCheckBefore # (dPC, dFP, self) 9523 movl rSELF, %eax 95241: 9525 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9526 jmp *dvmAsmInstructionStart+(43*4) 9527 9528/* ------------------------------ */ 9529.L_ALT_OP_SPARSE_SWITCH: /* 0x2c */ 9530/* File: x86/alt_stub.S */ 9531/* 9532 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9533 * any interesting requests and then jump to the real instruction 9534 * handler. Unlike the Arm handler, we can't do this as a tail call 9535 * because rIBASE is caller save and we need to reload it. 9536 * 9537 * Note that unlike in the Arm implementation, we should never arrive 9538 * here with a zero breakFlag because we always refresh rIBASE on 9539 * return. 9540 */ 9541 EXPORT_PC 9542 movl rSELF, %eax 9543 movl rPC, OUT_ARG0(%esp) 9544 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9545 movl rFP, OUT_ARG1(%esp) 9546 je 1f # reload rIBASE & resume if not 9547 movl %eax, OUT_ARG2(%esp) 9548 call dvmCheckBefore # (dPC, dFP, self) 9549 movl rSELF, %eax 95501: 9551 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9552 jmp *dvmAsmInstructionStart+(44*4) 9553 9554/* ------------------------------ */ 9555.L_ALT_OP_CMPL_FLOAT: /* 0x2d */ 9556/* File: x86/alt_stub.S */ 9557/* 9558 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9559 * any interesting requests and then jump to the real instruction 9560 * handler. Unlike the Arm handler, we can't do this as a tail call 9561 * because rIBASE is caller save and we need to reload it. 9562 * 9563 * Note that unlike in the Arm implementation, we should never arrive 9564 * here with a zero breakFlag because we always refresh rIBASE on 9565 * return. 9566 */ 9567 EXPORT_PC 9568 movl rSELF, %eax 9569 movl rPC, OUT_ARG0(%esp) 9570 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9571 movl rFP, OUT_ARG1(%esp) 9572 je 1f # reload rIBASE & resume if not 9573 movl %eax, OUT_ARG2(%esp) 9574 call dvmCheckBefore # (dPC, dFP, self) 9575 movl rSELF, %eax 95761: 9577 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9578 jmp *dvmAsmInstructionStart+(45*4) 9579 9580/* ------------------------------ */ 9581.L_ALT_OP_CMPG_FLOAT: /* 0x2e */ 9582/* File: x86/alt_stub.S */ 9583/* 9584 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9585 * any interesting requests and then jump to the real instruction 9586 * handler. Unlike the Arm handler, we can't do this as a tail call 9587 * because rIBASE is caller save and we need to reload it. 9588 * 9589 * Note that unlike in the Arm implementation, we should never arrive 9590 * here with a zero breakFlag because we always refresh rIBASE on 9591 * return. 9592 */ 9593 EXPORT_PC 9594 movl rSELF, %eax 9595 movl rPC, OUT_ARG0(%esp) 9596 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9597 movl rFP, OUT_ARG1(%esp) 9598 je 1f # reload rIBASE & resume if not 9599 movl %eax, OUT_ARG2(%esp) 9600 call dvmCheckBefore # (dPC, dFP, self) 9601 movl rSELF, %eax 96021: 9603 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9604 jmp *dvmAsmInstructionStart+(46*4) 9605 9606/* ------------------------------ */ 9607.L_ALT_OP_CMPL_DOUBLE: /* 0x2f */ 9608/* File: x86/alt_stub.S */ 9609/* 9610 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9611 * any interesting requests and then jump to the real instruction 9612 * handler. Unlike the Arm handler, we can't do this as a tail call 9613 * because rIBASE is caller save and we need to reload it. 9614 * 9615 * Note that unlike in the Arm implementation, we should never arrive 9616 * here with a zero breakFlag because we always refresh rIBASE on 9617 * return. 9618 */ 9619 EXPORT_PC 9620 movl rSELF, %eax 9621 movl rPC, OUT_ARG0(%esp) 9622 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9623 movl rFP, OUT_ARG1(%esp) 9624 je 1f # reload rIBASE & resume if not 9625 movl %eax, OUT_ARG2(%esp) 9626 call dvmCheckBefore # (dPC, dFP, self) 9627 movl rSELF, %eax 96281: 9629 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9630 jmp *dvmAsmInstructionStart+(47*4) 9631 9632/* ------------------------------ */ 9633.L_ALT_OP_CMPG_DOUBLE: /* 0x30 */ 9634/* File: x86/alt_stub.S */ 9635/* 9636 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9637 * any interesting requests and then jump to the real instruction 9638 * handler. Unlike the Arm handler, we can't do this as a tail call 9639 * because rIBASE is caller save and we need to reload it. 9640 * 9641 * Note that unlike in the Arm implementation, we should never arrive 9642 * here with a zero breakFlag because we always refresh rIBASE on 9643 * return. 9644 */ 9645 EXPORT_PC 9646 movl rSELF, %eax 9647 movl rPC, OUT_ARG0(%esp) 9648 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9649 movl rFP, OUT_ARG1(%esp) 9650 je 1f # reload rIBASE & resume if not 9651 movl %eax, OUT_ARG2(%esp) 9652 call dvmCheckBefore # (dPC, dFP, self) 9653 movl rSELF, %eax 96541: 9655 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9656 jmp *dvmAsmInstructionStart+(48*4) 9657 9658/* ------------------------------ */ 9659.L_ALT_OP_CMP_LONG: /* 0x31 */ 9660/* File: x86/alt_stub.S */ 9661/* 9662 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9663 * any interesting requests and then jump to the real instruction 9664 * handler. Unlike the Arm handler, we can't do this as a tail call 9665 * because rIBASE is caller save and we need to reload it. 9666 * 9667 * Note that unlike in the Arm implementation, we should never arrive 9668 * here with a zero breakFlag because we always refresh rIBASE on 9669 * return. 9670 */ 9671 EXPORT_PC 9672 movl rSELF, %eax 9673 movl rPC, OUT_ARG0(%esp) 9674 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9675 movl rFP, OUT_ARG1(%esp) 9676 je 1f # reload rIBASE & resume if not 9677 movl %eax, OUT_ARG2(%esp) 9678 call dvmCheckBefore # (dPC, dFP, self) 9679 movl rSELF, %eax 96801: 9681 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9682 jmp *dvmAsmInstructionStart+(49*4) 9683 9684/* ------------------------------ */ 9685.L_ALT_OP_IF_EQ: /* 0x32 */ 9686/* File: x86/alt_stub.S */ 9687/* 9688 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9689 * any interesting requests and then jump to the real instruction 9690 * handler. Unlike the Arm handler, we can't do this as a tail call 9691 * because rIBASE is caller save and we need to reload it. 9692 * 9693 * Note that unlike in the Arm implementation, we should never arrive 9694 * here with a zero breakFlag because we always refresh rIBASE on 9695 * return. 9696 */ 9697 EXPORT_PC 9698 movl rSELF, %eax 9699 movl rPC, OUT_ARG0(%esp) 9700 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9701 movl rFP, OUT_ARG1(%esp) 9702 je 1f # reload rIBASE & resume if not 9703 movl %eax, OUT_ARG2(%esp) 9704 call dvmCheckBefore # (dPC, dFP, self) 9705 movl rSELF, %eax 97061: 9707 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9708 jmp *dvmAsmInstructionStart+(50*4) 9709 9710/* ------------------------------ */ 9711.L_ALT_OP_IF_NE: /* 0x33 */ 9712/* File: x86/alt_stub.S */ 9713/* 9714 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9715 * any interesting requests and then jump to the real instruction 9716 * handler. Unlike the Arm handler, we can't do this as a tail call 9717 * because rIBASE is caller save and we need to reload it. 9718 * 9719 * Note that unlike in the Arm implementation, we should never arrive 9720 * here with a zero breakFlag because we always refresh rIBASE on 9721 * return. 9722 */ 9723 EXPORT_PC 9724 movl rSELF, %eax 9725 movl rPC, OUT_ARG0(%esp) 9726 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9727 movl rFP, OUT_ARG1(%esp) 9728 je 1f # reload rIBASE & resume if not 9729 movl %eax, OUT_ARG2(%esp) 9730 call dvmCheckBefore # (dPC, dFP, self) 9731 movl rSELF, %eax 97321: 9733 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9734 jmp *dvmAsmInstructionStart+(51*4) 9735 9736/* ------------------------------ */ 9737.L_ALT_OP_IF_LT: /* 0x34 */ 9738/* File: x86/alt_stub.S */ 9739/* 9740 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9741 * any interesting requests and then jump to the real instruction 9742 * handler. Unlike the Arm handler, we can't do this as a tail call 9743 * because rIBASE is caller save and we need to reload it. 9744 * 9745 * Note that unlike in the Arm implementation, we should never arrive 9746 * here with a zero breakFlag because we always refresh rIBASE on 9747 * return. 9748 */ 9749 EXPORT_PC 9750 movl rSELF, %eax 9751 movl rPC, OUT_ARG0(%esp) 9752 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9753 movl rFP, OUT_ARG1(%esp) 9754 je 1f # reload rIBASE & resume if not 9755 movl %eax, OUT_ARG2(%esp) 9756 call dvmCheckBefore # (dPC, dFP, self) 9757 movl rSELF, %eax 97581: 9759 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9760 jmp *dvmAsmInstructionStart+(52*4) 9761 9762/* ------------------------------ */ 9763.L_ALT_OP_IF_GE: /* 0x35 */ 9764/* File: x86/alt_stub.S */ 9765/* 9766 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9767 * any interesting requests and then jump to the real instruction 9768 * handler. Unlike the Arm handler, we can't do this as a tail call 9769 * because rIBASE is caller save and we need to reload it. 9770 * 9771 * Note that unlike in the Arm implementation, we should never arrive 9772 * here with a zero breakFlag because we always refresh rIBASE on 9773 * return. 9774 */ 9775 EXPORT_PC 9776 movl rSELF, %eax 9777 movl rPC, OUT_ARG0(%esp) 9778 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9779 movl rFP, OUT_ARG1(%esp) 9780 je 1f # reload rIBASE & resume if not 9781 movl %eax, OUT_ARG2(%esp) 9782 call dvmCheckBefore # (dPC, dFP, self) 9783 movl rSELF, %eax 97841: 9785 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9786 jmp *dvmAsmInstructionStart+(53*4) 9787 9788/* ------------------------------ */ 9789.L_ALT_OP_IF_GT: /* 0x36 */ 9790/* File: x86/alt_stub.S */ 9791/* 9792 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9793 * any interesting requests and then jump to the real instruction 9794 * handler. Unlike the Arm handler, we can't do this as a tail call 9795 * because rIBASE is caller save and we need to reload it. 9796 * 9797 * Note that unlike in the Arm implementation, we should never arrive 9798 * here with a zero breakFlag because we always refresh rIBASE on 9799 * return. 9800 */ 9801 EXPORT_PC 9802 movl rSELF, %eax 9803 movl rPC, OUT_ARG0(%esp) 9804 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9805 movl rFP, OUT_ARG1(%esp) 9806 je 1f # reload rIBASE & resume if not 9807 movl %eax, OUT_ARG2(%esp) 9808 call dvmCheckBefore # (dPC, dFP, self) 9809 movl rSELF, %eax 98101: 9811 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9812 jmp *dvmAsmInstructionStart+(54*4) 9813 9814/* ------------------------------ */ 9815.L_ALT_OP_IF_LE: /* 0x37 */ 9816/* File: x86/alt_stub.S */ 9817/* 9818 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9819 * any interesting requests and then jump to the real instruction 9820 * handler. Unlike the Arm handler, we can't do this as a tail call 9821 * because rIBASE is caller save and we need to reload it. 9822 * 9823 * Note that unlike in the Arm implementation, we should never arrive 9824 * here with a zero breakFlag because we always refresh rIBASE on 9825 * return. 9826 */ 9827 EXPORT_PC 9828 movl rSELF, %eax 9829 movl rPC, OUT_ARG0(%esp) 9830 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9831 movl rFP, OUT_ARG1(%esp) 9832 je 1f # reload rIBASE & resume if not 9833 movl %eax, OUT_ARG2(%esp) 9834 call dvmCheckBefore # (dPC, dFP, self) 9835 movl rSELF, %eax 98361: 9837 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9838 jmp *dvmAsmInstructionStart+(55*4) 9839 9840/* ------------------------------ */ 9841.L_ALT_OP_IF_EQZ: /* 0x38 */ 9842/* File: x86/alt_stub.S */ 9843/* 9844 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9845 * any interesting requests and then jump to the real instruction 9846 * handler. Unlike the Arm handler, we can't do this as a tail call 9847 * because rIBASE is caller save and we need to reload it. 9848 * 9849 * Note that unlike in the Arm implementation, we should never arrive 9850 * here with a zero breakFlag because we always refresh rIBASE on 9851 * return. 9852 */ 9853 EXPORT_PC 9854 movl rSELF, %eax 9855 movl rPC, OUT_ARG0(%esp) 9856 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9857 movl rFP, OUT_ARG1(%esp) 9858 je 1f # reload rIBASE & resume if not 9859 movl %eax, OUT_ARG2(%esp) 9860 call dvmCheckBefore # (dPC, dFP, self) 9861 movl rSELF, %eax 98621: 9863 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9864 jmp *dvmAsmInstructionStart+(56*4) 9865 9866/* ------------------------------ */ 9867.L_ALT_OP_IF_NEZ: /* 0x39 */ 9868/* File: x86/alt_stub.S */ 9869/* 9870 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9871 * any interesting requests and then jump to the real instruction 9872 * handler. Unlike the Arm handler, we can't do this as a tail call 9873 * because rIBASE is caller save and we need to reload it. 9874 * 9875 * Note that unlike in the Arm implementation, we should never arrive 9876 * here with a zero breakFlag because we always refresh rIBASE on 9877 * return. 9878 */ 9879 EXPORT_PC 9880 movl rSELF, %eax 9881 movl rPC, OUT_ARG0(%esp) 9882 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9883 movl rFP, OUT_ARG1(%esp) 9884 je 1f # reload rIBASE & resume if not 9885 movl %eax, OUT_ARG2(%esp) 9886 call dvmCheckBefore # (dPC, dFP, self) 9887 movl rSELF, %eax 98881: 9889 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9890 jmp *dvmAsmInstructionStart+(57*4) 9891 9892/* ------------------------------ */ 9893.L_ALT_OP_IF_LTZ: /* 0x3a */ 9894/* File: x86/alt_stub.S */ 9895/* 9896 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9897 * any interesting requests and then jump to the real instruction 9898 * handler. Unlike the Arm handler, we can't do this as a tail call 9899 * because rIBASE is caller save and we need to reload it. 9900 * 9901 * Note that unlike in the Arm implementation, we should never arrive 9902 * here with a zero breakFlag because we always refresh rIBASE on 9903 * return. 9904 */ 9905 EXPORT_PC 9906 movl rSELF, %eax 9907 movl rPC, OUT_ARG0(%esp) 9908 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9909 movl rFP, OUT_ARG1(%esp) 9910 je 1f # reload rIBASE & resume if not 9911 movl %eax, OUT_ARG2(%esp) 9912 call dvmCheckBefore # (dPC, dFP, self) 9913 movl rSELF, %eax 99141: 9915 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9916 jmp *dvmAsmInstructionStart+(58*4) 9917 9918/* ------------------------------ */ 9919.L_ALT_OP_IF_GEZ: /* 0x3b */ 9920/* File: x86/alt_stub.S */ 9921/* 9922 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9923 * any interesting requests and then jump to the real instruction 9924 * handler. Unlike the Arm handler, we can't do this as a tail call 9925 * because rIBASE is caller save and we need to reload it. 9926 * 9927 * Note that unlike in the Arm implementation, we should never arrive 9928 * here with a zero breakFlag because we always refresh rIBASE on 9929 * return. 9930 */ 9931 EXPORT_PC 9932 movl rSELF, %eax 9933 movl rPC, OUT_ARG0(%esp) 9934 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9935 movl rFP, OUT_ARG1(%esp) 9936 je 1f # reload rIBASE & resume if not 9937 movl %eax, OUT_ARG2(%esp) 9938 call dvmCheckBefore # (dPC, dFP, self) 9939 movl rSELF, %eax 99401: 9941 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9942 jmp *dvmAsmInstructionStart+(59*4) 9943 9944/* ------------------------------ */ 9945.L_ALT_OP_IF_GTZ: /* 0x3c */ 9946/* File: x86/alt_stub.S */ 9947/* 9948 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9949 * any interesting requests and then jump to the real instruction 9950 * handler. Unlike the Arm handler, we can't do this as a tail call 9951 * because rIBASE is caller save and we need to reload it. 9952 * 9953 * Note that unlike in the Arm implementation, we should never arrive 9954 * here with a zero breakFlag because we always refresh rIBASE on 9955 * return. 9956 */ 9957 EXPORT_PC 9958 movl rSELF, %eax 9959 movl rPC, OUT_ARG0(%esp) 9960 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9961 movl rFP, OUT_ARG1(%esp) 9962 je 1f # reload rIBASE & resume if not 9963 movl %eax, OUT_ARG2(%esp) 9964 call dvmCheckBefore # (dPC, dFP, self) 9965 movl rSELF, %eax 99661: 9967 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9968 jmp *dvmAsmInstructionStart+(60*4) 9969 9970/* ------------------------------ */ 9971.L_ALT_OP_IF_LEZ: /* 0x3d */ 9972/* File: x86/alt_stub.S */ 9973/* 9974 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9975 * any interesting requests and then jump to the real instruction 9976 * handler. Unlike the Arm handler, we can't do this as a tail call 9977 * because rIBASE is caller save and we need to reload it. 9978 * 9979 * Note that unlike in the Arm implementation, we should never arrive 9980 * here with a zero breakFlag because we always refresh rIBASE on 9981 * return. 9982 */ 9983 EXPORT_PC 9984 movl rSELF, %eax 9985 movl rPC, OUT_ARG0(%esp) 9986 cmpb $0,offThread_breakFlags(%eax) # anything to do? 9987 movl rFP, OUT_ARG1(%esp) 9988 je 1f # reload rIBASE & resume if not 9989 movl %eax, OUT_ARG2(%esp) 9990 call dvmCheckBefore # (dPC, dFP, self) 9991 movl rSELF, %eax 99921: 9993 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 9994 jmp *dvmAsmInstructionStart+(61*4) 9995 9996/* ------------------------------ */ 9997.L_ALT_OP_UNUSED_3E: /* 0x3e */ 9998/* File: x86/alt_stub.S */ 9999/* 10000 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10001 * any interesting requests and then jump to the real instruction 10002 * handler. Unlike the Arm handler, we can't do this as a tail call 10003 * because rIBASE is caller save and we need to reload it. 10004 * 10005 * Note that unlike in the Arm implementation, we should never arrive 10006 * here with a zero breakFlag because we always refresh rIBASE on 10007 * return. 10008 */ 10009 EXPORT_PC 10010 movl rSELF, %eax 10011 movl rPC, OUT_ARG0(%esp) 10012 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10013 movl rFP, OUT_ARG1(%esp) 10014 je 1f # reload rIBASE & resume if not 10015 movl %eax, OUT_ARG2(%esp) 10016 call dvmCheckBefore # (dPC, dFP, self) 10017 movl rSELF, %eax 100181: 10019 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10020 jmp *dvmAsmInstructionStart+(62*4) 10021 10022/* ------------------------------ */ 10023.L_ALT_OP_UNUSED_3F: /* 0x3f */ 10024/* File: x86/alt_stub.S */ 10025/* 10026 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10027 * any interesting requests and then jump to the real instruction 10028 * handler. Unlike the Arm handler, we can't do this as a tail call 10029 * because rIBASE is caller save and we need to reload it. 10030 * 10031 * Note that unlike in the Arm implementation, we should never arrive 10032 * here with a zero breakFlag because we always refresh rIBASE on 10033 * return. 10034 */ 10035 EXPORT_PC 10036 movl rSELF, %eax 10037 movl rPC, OUT_ARG0(%esp) 10038 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10039 movl rFP, OUT_ARG1(%esp) 10040 je 1f # reload rIBASE & resume if not 10041 movl %eax, OUT_ARG2(%esp) 10042 call dvmCheckBefore # (dPC, dFP, self) 10043 movl rSELF, %eax 100441: 10045 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10046 jmp *dvmAsmInstructionStart+(63*4) 10047 10048/* ------------------------------ */ 10049.L_ALT_OP_UNUSED_40: /* 0x40 */ 10050/* File: x86/alt_stub.S */ 10051/* 10052 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10053 * any interesting requests and then jump to the real instruction 10054 * handler. Unlike the Arm handler, we can't do this as a tail call 10055 * because rIBASE is caller save and we need to reload it. 10056 * 10057 * Note that unlike in the Arm implementation, we should never arrive 10058 * here with a zero breakFlag because we always refresh rIBASE on 10059 * return. 10060 */ 10061 EXPORT_PC 10062 movl rSELF, %eax 10063 movl rPC, OUT_ARG0(%esp) 10064 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10065 movl rFP, OUT_ARG1(%esp) 10066 je 1f # reload rIBASE & resume if not 10067 movl %eax, OUT_ARG2(%esp) 10068 call dvmCheckBefore # (dPC, dFP, self) 10069 movl rSELF, %eax 100701: 10071 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10072 jmp *dvmAsmInstructionStart+(64*4) 10073 10074/* ------------------------------ */ 10075.L_ALT_OP_UNUSED_41: /* 0x41 */ 10076/* File: x86/alt_stub.S */ 10077/* 10078 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10079 * any interesting requests and then jump to the real instruction 10080 * handler. Unlike the Arm handler, we can't do this as a tail call 10081 * because rIBASE is caller save and we need to reload it. 10082 * 10083 * Note that unlike in the Arm implementation, we should never arrive 10084 * here with a zero breakFlag because we always refresh rIBASE on 10085 * return. 10086 */ 10087 EXPORT_PC 10088 movl rSELF, %eax 10089 movl rPC, OUT_ARG0(%esp) 10090 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10091 movl rFP, OUT_ARG1(%esp) 10092 je 1f # reload rIBASE & resume if not 10093 movl %eax, OUT_ARG2(%esp) 10094 call dvmCheckBefore # (dPC, dFP, self) 10095 movl rSELF, %eax 100961: 10097 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10098 jmp *dvmAsmInstructionStart+(65*4) 10099 10100/* ------------------------------ */ 10101.L_ALT_OP_UNUSED_42: /* 0x42 */ 10102/* File: x86/alt_stub.S */ 10103/* 10104 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10105 * any interesting requests and then jump to the real instruction 10106 * handler. Unlike the Arm handler, we can't do this as a tail call 10107 * because rIBASE is caller save and we need to reload it. 10108 * 10109 * Note that unlike in the Arm implementation, we should never arrive 10110 * here with a zero breakFlag because we always refresh rIBASE on 10111 * return. 10112 */ 10113 EXPORT_PC 10114 movl rSELF, %eax 10115 movl rPC, OUT_ARG0(%esp) 10116 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10117 movl rFP, OUT_ARG1(%esp) 10118 je 1f # reload rIBASE & resume if not 10119 movl %eax, OUT_ARG2(%esp) 10120 call dvmCheckBefore # (dPC, dFP, self) 10121 movl rSELF, %eax 101221: 10123 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10124 jmp *dvmAsmInstructionStart+(66*4) 10125 10126/* ------------------------------ */ 10127.L_ALT_OP_UNUSED_43: /* 0x43 */ 10128/* File: x86/alt_stub.S */ 10129/* 10130 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10131 * any interesting requests and then jump to the real instruction 10132 * handler. Unlike the Arm handler, we can't do this as a tail call 10133 * because rIBASE is caller save and we need to reload it. 10134 * 10135 * Note that unlike in the Arm implementation, we should never arrive 10136 * here with a zero breakFlag because we always refresh rIBASE on 10137 * return. 10138 */ 10139 EXPORT_PC 10140 movl rSELF, %eax 10141 movl rPC, OUT_ARG0(%esp) 10142 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10143 movl rFP, OUT_ARG1(%esp) 10144 je 1f # reload rIBASE & resume if not 10145 movl %eax, OUT_ARG2(%esp) 10146 call dvmCheckBefore # (dPC, dFP, self) 10147 movl rSELF, %eax 101481: 10149 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10150 jmp *dvmAsmInstructionStart+(67*4) 10151 10152/* ------------------------------ */ 10153.L_ALT_OP_AGET: /* 0x44 */ 10154/* File: x86/alt_stub.S */ 10155/* 10156 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10157 * any interesting requests and then jump to the real instruction 10158 * handler. Unlike the Arm handler, we can't do this as a tail call 10159 * because rIBASE is caller save and we need to reload it. 10160 * 10161 * Note that unlike in the Arm implementation, we should never arrive 10162 * here with a zero breakFlag because we always refresh rIBASE on 10163 * return. 10164 */ 10165 EXPORT_PC 10166 movl rSELF, %eax 10167 movl rPC, OUT_ARG0(%esp) 10168 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10169 movl rFP, OUT_ARG1(%esp) 10170 je 1f # reload rIBASE & resume if not 10171 movl %eax, OUT_ARG2(%esp) 10172 call dvmCheckBefore # (dPC, dFP, self) 10173 movl rSELF, %eax 101741: 10175 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10176 jmp *dvmAsmInstructionStart+(68*4) 10177 10178/* ------------------------------ */ 10179.L_ALT_OP_AGET_WIDE: /* 0x45 */ 10180/* File: x86/alt_stub.S */ 10181/* 10182 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10183 * any interesting requests and then jump to the real instruction 10184 * handler. Unlike the Arm handler, we can't do this as a tail call 10185 * because rIBASE is caller save and we need to reload it. 10186 * 10187 * Note that unlike in the Arm implementation, we should never arrive 10188 * here with a zero breakFlag because we always refresh rIBASE on 10189 * return. 10190 */ 10191 EXPORT_PC 10192 movl rSELF, %eax 10193 movl rPC, OUT_ARG0(%esp) 10194 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10195 movl rFP, OUT_ARG1(%esp) 10196 je 1f # reload rIBASE & resume if not 10197 movl %eax, OUT_ARG2(%esp) 10198 call dvmCheckBefore # (dPC, dFP, self) 10199 movl rSELF, %eax 102001: 10201 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10202 jmp *dvmAsmInstructionStart+(69*4) 10203 10204/* ------------------------------ */ 10205.L_ALT_OP_AGET_OBJECT: /* 0x46 */ 10206/* File: x86/alt_stub.S */ 10207/* 10208 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10209 * any interesting requests and then jump to the real instruction 10210 * handler. Unlike the Arm handler, we can't do this as a tail call 10211 * because rIBASE is caller save and we need to reload it. 10212 * 10213 * Note that unlike in the Arm implementation, we should never arrive 10214 * here with a zero breakFlag because we always refresh rIBASE on 10215 * return. 10216 */ 10217 EXPORT_PC 10218 movl rSELF, %eax 10219 movl rPC, OUT_ARG0(%esp) 10220 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10221 movl rFP, OUT_ARG1(%esp) 10222 je 1f # reload rIBASE & resume if not 10223 movl %eax, OUT_ARG2(%esp) 10224 call dvmCheckBefore # (dPC, dFP, self) 10225 movl rSELF, %eax 102261: 10227 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10228 jmp *dvmAsmInstructionStart+(70*4) 10229 10230/* ------------------------------ */ 10231.L_ALT_OP_AGET_BOOLEAN: /* 0x47 */ 10232/* File: x86/alt_stub.S */ 10233/* 10234 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10235 * any interesting requests and then jump to the real instruction 10236 * handler. Unlike the Arm handler, we can't do this as a tail call 10237 * because rIBASE is caller save and we need to reload it. 10238 * 10239 * Note that unlike in the Arm implementation, we should never arrive 10240 * here with a zero breakFlag because we always refresh rIBASE on 10241 * return. 10242 */ 10243 EXPORT_PC 10244 movl rSELF, %eax 10245 movl rPC, OUT_ARG0(%esp) 10246 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10247 movl rFP, OUT_ARG1(%esp) 10248 je 1f # reload rIBASE & resume if not 10249 movl %eax, OUT_ARG2(%esp) 10250 call dvmCheckBefore # (dPC, dFP, self) 10251 movl rSELF, %eax 102521: 10253 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10254 jmp *dvmAsmInstructionStart+(71*4) 10255 10256/* ------------------------------ */ 10257.L_ALT_OP_AGET_BYTE: /* 0x48 */ 10258/* File: x86/alt_stub.S */ 10259/* 10260 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10261 * any interesting requests and then jump to the real instruction 10262 * handler. Unlike the Arm handler, we can't do this as a tail call 10263 * because rIBASE is caller save and we need to reload it. 10264 * 10265 * Note that unlike in the Arm implementation, we should never arrive 10266 * here with a zero breakFlag because we always refresh rIBASE on 10267 * return. 10268 */ 10269 EXPORT_PC 10270 movl rSELF, %eax 10271 movl rPC, OUT_ARG0(%esp) 10272 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10273 movl rFP, OUT_ARG1(%esp) 10274 je 1f # reload rIBASE & resume if not 10275 movl %eax, OUT_ARG2(%esp) 10276 call dvmCheckBefore # (dPC, dFP, self) 10277 movl rSELF, %eax 102781: 10279 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10280 jmp *dvmAsmInstructionStart+(72*4) 10281 10282/* ------------------------------ */ 10283.L_ALT_OP_AGET_CHAR: /* 0x49 */ 10284/* File: x86/alt_stub.S */ 10285/* 10286 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10287 * any interesting requests and then jump to the real instruction 10288 * handler. Unlike the Arm handler, we can't do this as a tail call 10289 * because rIBASE is caller save and we need to reload it. 10290 * 10291 * Note that unlike in the Arm implementation, we should never arrive 10292 * here with a zero breakFlag because we always refresh rIBASE on 10293 * return. 10294 */ 10295 EXPORT_PC 10296 movl rSELF, %eax 10297 movl rPC, OUT_ARG0(%esp) 10298 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10299 movl rFP, OUT_ARG1(%esp) 10300 je 1f # reload rIBASE & resume if not 10301 movl %eax, OUT_ARG2(%esp) 10302 call dvmCheckBefore # (dPC, dFP, self) 10303 movl rSELF, %eax 103041: 10305 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10306 jmp *dvmAsmInstructionStart+(73*4) 10307 10308/* ------------------------------ */ 10309.L_ALT_OP_AGET_SHORT: /* 0x4a */ 10310/* File: x86/alt_stub.S */ 10311/* 10312 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10313 * any interesting requests and then jump to the real instruction 10314 * handler. Unlike the Arm handler, we can't do this as a tail call 10315 * because rIBASE is caller save and we need to reload it. 10316 * 10317 * Note that unlike in the Arm implementation, we should never arrive 10318 * here with a zero breakFlag because we always refresh rIBASE on 10319 * return. 10320 */ 10321 EXPORT_PC 10322 movl rSELF, %eax 10323 movl rPC, OUT_ARG0(%esp) 10324 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10325 movl rFP, OUT_ARG1(%esp) 10326 je 1f # reload rIBASE & resume if not 10327 movl %eax, OUT_ARG2(%esp) 10328 call dvmCheckBefore # (dPC, dFP, self) 10329 movl rSELF, %eax 103301: 10331 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10332 jmp *dvmAsmInstructionStart+(74*4) 10333 10334/* ------------------------------ */ 10335.L_ALT_OP_APUT: /* 0x4b */ 10336/* File: x86/alt_stub.S */ 10337/* 10338 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10339 * any interesting requests and then jump to the real instruction 10340 * handler. Unlike the Arm handler, we can't do this as a tail call 10341 * because rIBASE is caller save and we need to reload it. 10342 * 10343 * Note that unlike in the Arm implementation, we should never arrive 10344 * here with a zero breakFlag because we always refresh rIBASE on 10345 * return. 10346 */ 10347 EXPORT_PC 10348 movl rSELF, %eax 10349 movl rPC, OUT_ARG0(%esp) 10350 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10351 movl rFP, OUT_ARG1(%esp) 10352 je 1f # reload rIBASE & resume if not 10353 movl %eax, OUT_ARG2(%esp) 10354 call dvmCheckBefore # (dPC, dFP, self) 10355 movl rSELF, %eax 103561: 10357 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10358 jmp *dvmAsmInstructionStart+(75*4) 10359 10360/* ------------------------------ */ 10361.L_ALT_OP_APUT_WIDE: /* 0x4c */ 10362/* File: x86/alt_stub.S */ 10363/* 10364 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10365 * any interesting requests and then jump to the real instruction 10366 * handler. Unlike the Arm handler, we can't do this as a tail call 10367 * because rIBASE is caller save and we need to reload it. 10368 * 10369 * Note that unlike in the Arm implementation, we should never arrive 10370 * here with a zero breakFlag because we always refresh rIBASE on 10371 * return. 10372 */ 10373 EXPORT_PC 10374 movl rSELF, %eax 10375 movl rPC, OUT_ARG0(%esp) 10376 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10377 movl rFP, OUT_ARG1(%esp) 10378 je 1f # reload rIBASE & resume if not 10379 movl %eax, OUT_ARG2(%esp) 10380 call dvmCheckBefore # (dPC, dFP, self) 10381 movl rSELF, %eax 103821: 10383 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10384 jmp *dvmAsmInstructionStart+(76*4) 10385 10386/* ------------------------------ */ 10387.L_ALT_OP_APUT_OBJECT: /* 0x4d */ 10388/* File: x86/alt_stub.S */ 10389/* 10390 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10391 * any interesting requests and then jump to the real instruction 10392 * handler. Unlike the Arm handler, we can't do this as a tail call 10393 * because rIBASE is caller save and we need to reload it. 10394 * 10395 * Note that unlike in the Arm implementation, we should never arrive 10396 * here with a zero breakFlag because we always refresh rIBASE on 10397 * return. 10398 */ 10399 EXPORT_PC 10400 movl rSELF, %eax 10401 movl rPC, OUT_ARG0(%esp) 10402 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10403 movl rFP, OUT_ARG1(%esp) 10404 je 1f # reload rIBASE & resume if not 10405 movl %eax, OUT_ARG2(%esp) 10406 call dvmCheckBefore # (dPC, dFP, self) 10407 movl rSELF, %eax 104081: 10409 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10410 jmp *dvmAsmInstructionStart+(77*4) 10411 10412/* ------------------------------ */ 10413.L_ALT_OP_APUT_BOOLEAN: /* 0x4e */ 10414/* File: x86/alt_stub.S */ 10415/* 10416 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10417 * any interesting requests and then jump to the real instruction 10418 * handler. Unlike the Arm handler, we can't do this as a tail call 10419 * because rIBASE is caller save and we need to reload it. 10420 * 10421 * Note that unlike in the Arm implementation, we should never arrive 10422 * here with a zero breakFlag because we always refresh rIBASE on 10423 * return. 10424 */ 10425 EXPORT_PC 10426 movl rSELF, %eax 10427 movl rPC, OUT_ARG0(%esp) 10428 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10429 movl rFP, OUT_ARG1(%esp) 10430 je 1f # reload rIBASE & resume if not 10431 movl %eax, OUT_ARG2(%esp) 10432 call dvmCheckBefore # (dPC, dFP, self) 10433 movl rSELF, %eax 104341: 10435 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10436 jmp *dvmAsmInstructionStart+(78*4) 10437 10438/* ------------------------------ */ 10439.L_ALT_OP_APUT_BYTE: /* 0x4f */ 10440/* File: x86/alt_stub.S */ 10441/* 10442 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10443 * any interesting requests and then jump to the real instruction 10444 * handler. Unlike the Arm handler, we can't do this as a tail call 10445 * because rIBASE is caller save and we need to reload it. 10446 * 10447 * Note that unlike in the Arm implementation, we should never arrive 10448 * here with a zero breakFlag because we always refresh rIBASE on 10449 * return. 10450 */ 10451 EXPORT_PC 10452 movl rSELF, %eax 10453 movl rPC, OUT_ARG0(%esp) 10454 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10455 movl rFP, OUT_ARG1(%esp) 10456 je 1f # reload rIBASE & resume if not 10457 movl %eax, OUT_ARG2(%esp) 10458 call dvmCheckBefore # (dPC, dFP, self) 10459 movl rSELF, %eax 104601: 10461 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10462 jmp *dvmAsmInstructionStart+(79*4) 10463 10464/* ------------------------------ */ 10465.L_ALT_OP_APUT_CHAR: /* 0x50 */ 10466/* File: x86/alt_stub.S */ 10467/* 10468 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10469 * any interesting requests and then jump to the real instruction 10470 * handler. Unlike the Arm handler, we can't do this as a tail call 10471 * because rIBASE is caller save and we need to reload it. 10472 * 10473 * Note that unlike in the Arm implementation, we should never arrive 10474 * here with a zero breakFlag because we always refresh rIBASE on 10475 * return. 10476 */ 10477 EXPORT_PC 10478 movl rSELF, %eax 10479 movl rPC, OUT_ARG0(%esp) 10480 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10481 movl rFP, OUT_ARG1(%esp) 10482 je 1f # reload rIBASE & resume if not 10483 movl %eax, OUT_ARG2(%esp) 10484 call dvmCheckBefore # (dPC, dFP, self) 10485 movl rSELF, %eax 104861: 10487 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10488 jmp *dvmAsmInstructionStart+(80*4) 10489 10490/* ------------------------------ */ 10491.L_ALT_OP_APUT_SHORT: /* 0x51 */ 10492/* File: x86/alt_stub.S */ 10493/* 10494 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10495 * any interesting requests and then jump to the real instruction 10496 * handler. Unlike the Arm handler, we can't do this as a tail call 10497 * because rIBASE is caller save and we need to reload it. 10498 * 10499 * Note that unlike in the Arm implementation, we should never arrive 10500 * here with a zero breakFlag because we always refresh rIBASE on 10501 * return. 10502 */ 10503 EXPORT_PC 10504 movl rSELF, %eax 10505 movl rPC, OUT_ARG0(%esp) 10506 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10507 movl rFP, OUT_ARG1(%esp) 10508 je 1f # reload rIBASE & resume if not 10509 movl %eax, OUT_ARG2(%esp) 10510 call dvmCheckBefore # (dPC, dFP, self) 10511 movl rSELF, %eax 105121: 10513 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10514 jmp *dvmAsmInstructionStart+(81*4) 10515 10516/* ------------------------------ */ 10517.L_ALT_OP_IGET: /* 0x52 */ 10518/* File: x86/alt_stub.S */ 10519/* 10520 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10521 * any interesting requests and then jump to the real instruction 10522 * handler. Unlike the Arm handler, we can't do this as a tail call 10523 * because rIBASE is caller save and we need to reload it. 10524 * 10525 * Note that unlike in the Arm implementation, we should never arrive 10526 * here with a zero breakFlag because we always refresh rIBASE on 10527 * return. 10528 */ 10529 EXPORT_PC 10530 movl rSELF, %eax 10531 movl rPC, OUT_ARG0(%esp) 10532 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10533 movl rFP, OUT_ARG1(%esp) 10534 je 1f # reload rIBASE & resume if not 10535 movl %eax, OUT_ARG2(%esp) 10536 call dvmCheckBefore # (dPC, dFP, self) 10537 movl rSELF, %eax 105381: 10539 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10540 jmp *dvmAsmInstructionStart+(82*4) 10541 10542/* ------------------------------ */ 10543.L_ALT_OP_IGET_WIDE: /* 0x53 */ 10544/* File: x86/alt_stub.S */ 10545/* 10546 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10547 * any interesting requests and then jump to the real instruction 10548 * handler. Unlike the Arm handler, we can't do this as a tail call 10549 * because rIBASE is caller save and we need to reload it. 10550 * 10551 * Note that unlike in the Arm implementation, we should never arrive 10552 * here with a zero breakFlag because we always refresh rIBASE on 10553 * return. 10554 */ 10555 EXPORT_PC 10556 movl rSELF, %eax 10557 movl rPC, OUT_ARG0(%esp) 10558 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10559 movl rFP, OUT_ARG1(%esp) 10560 je 1f # reload rIBASE & resume if not 10561 movl %eax, OUT_ARG2(%esp) 10562 call dvmCheckBefore # (dPC, dFP, self) 10563 movl rSELF, %eax 105641: 10565 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10566 jmp *dvmAsmInstructionStart+(83*4) 10567 10568/* ------------------------------ */ 10569.L_ALT_OP_IGET_OBJECT: /* 0x54 */ 10570/* File: x86/alt_stub.S */ 10571/* 10572 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10573 * any interesting requests and then jump to the real instruction 10574 * handler. Unlike the Arm handler, we can't do this as a tail call 10575 * because rIBASE is caller save and we need to reload it. 10576 * 10577 * Note that unlike in the Arm implementation, we should never arrive 10578 * here with a zero breakFlag because we always refresh rIBASE on 10579 * return. 10580 */ 10581 EXPORT_PC 10582 movl rSELF, %eax 10583 movl rPC, OUT_ARG0(%esp) 10584 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10585 movl rFP, OUT_ARG1(%esp) 10586 je 1f # reload rIBASE & resume if not 10587 movl %eax, OUT_ARG2(%esp) 10588 call dvmCheckBefore # (dPC, dFP, self) 10589 movl rSELF, %eax 105901: 10591 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10592 jmp *dvmAsmInstructionStart+(84*4) 10593 10594/* ------------------------------ */ 10595.L_ALT_OP_IGET_BOOLEAN: /* 0x55 */ 10596/* File: x86/alt_stub.S */ 10597/* 10598 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10599 * any interesting requests and then jump to the real instruction 10600 * handler. Unlike the Arm handler, we can't do this as a tail call 10601 * because rIBASE is caller save and we need to reload it. 10602 * 10603 * Note that unlike in the Arm implementation, we should never arrive 10604 * here with a zero breakFlag because we always refresh rIBASE on 10605 * return. 10606 */ 10607 EXPORT_PC 10608 movl rSELF, %eax 10609 movl rPC, OUT_ARG0(%esp) 10610 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10611 movl rFP, OUT_ARG1(%esp) 10612 je 1f # reload rIBASE & resume if not 10613 movl %eax, OUT_ARG2(%esp) 10614 call dvmCheckBefore # (dPC, dFP, self) 10615 movl rSELF, %eax 106161: 10617 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10618 jmp *dvmAsmInstructionStart+(85*4) 10619 10620/* ------------------------------ */ 10621.L_ALT_OP_IGET_BYTE: /* 0x56 */ 10622/* File: x86/alt_stub.S */ 10623/* 10624 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10625 * any interesting requests and then jump to the real instruction 10626 * handler. Unlike the Arm handler, we can't do this as a tail call 10627 * because rIBASE is caller save and we need to reload it. 10628 * 10629 * Note that unlike in the Arm implementation, we should never arrive 10630 * here with a zero breakFlag because we always refresh rIBASE on 10631 * return. 10632 */ 10633 EXPORT_PC 10634 movl rSELF, %eax 10635 movl rPC, OUT_ARG0(%esp) 10636 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10637 movl rFP, OUT_ARG1(%esp) 10638 je 1f # reload rIBASE & resume if not 10639 movl %eax, OUT_ARG2(%esp) 10640 call dvmCheckBefore # (dPC, dFP, self) 10641 movl rSELF, %eax 106421: 10643 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10644 jmp *dvmAsmInstructionStart+(86*4) 10645 10646/* ------------------------------ */ 10647.L_ALT_OP_IGET_CHAR: /* 0x57 */ 10648/* File: x86/alt_stub.S */ 10649/* 10650 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10651 * any interesting requests and then jump to the real instruction 10652 * handler. Unlike the Arm handler, we can't do this as a tail call 10653 * because rIBASE is caller save and we need to reload it. 10654 * 10655 * Note that unlike in the Arm implementation, we should never arrive 10656 * here with a zero breakFlag because we always refresh rIBASE on 10657 * return. 10658 */ 10659 EXPORT_PC 10660 movl rSELF, %eax 10661 movl rPC, OUT_ARG0(%esp) 10662 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10663 movl rFP, OUT_ARG1(%esp) 10664 je 1f # reload rIBASE & resume if not 10665 movl %eax, OUT_ARG2(%esp) 10666 call dvmCheckBefore # (dPC, dFP, self) 10667 movl rSELF, %eax 106681: 10669 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10670 jmp *dvmAsmInstructionStart+(87*4) 10671 10672/* ------------------------------ */ 10673.L_ALT_OP_IGET_SHORT: /* 0x58 */ 10674/* File: x86/alt_stub.S */ 10675/* 10676 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10677 * any interesting requests and then jump to the real instruction 10678 * handler. Unlike the Arm handler, we can't do this as a tail call 10679 * because rIBASE is caller save and we need to reload it. 10680 * 10681 * Note that unlike in the Arm implementation, we should never arrive 10682 * here with a zero breakFlag because we always refresh rIBASE on 10683 * return. 10684 */ 10685 EXPORT_PC 10686 movl rSELF, %eax 10687 movl rPC, OUT_ARG0(%esp) 10688 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10689 movl rFP, OUT_ARG1(%esp) 10690 je 1f # reload rIBASE & resume if not 10691 movl %eax, OUT_ARG2(%esp) 10692 call dvmCheckBefore # (dPC, dFP, self) 10693 movl rSELF, %eax 106941: 10695 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10696 jmp *dvmAsmInstructionStart+(88*4) 10697 10698/* ------------------------------ */ 10699.L_ALT_OP_IPUT: /* 0x59 */ 10700/* File: x86/alt_stub.S */ 10701/* 10702 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10703 * any interesting requests and then jump to the real instruction 10704 * handler. Unlike the Arm handler, we can't do this as a tail call 10705 * because rIBASE is caller save and we need to reload it. 10706 * 10707 * Note that unlike in the Arm implementation, we should never arrive 10708 * here with a zero breakFlag because we always refresh rIBASE on 10709 * return. 10710 */ 10711 EXPORT_PC 10712 movl rSELF, %eax 10713 movl rPC, OUT_ARG0(%esp) 10714 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10715 movl rFP, OUT_ARG1(%esp) 10716 je 1f # reload rIBASE & resume if not 10717 movl %eax, OUT_ARG2(%esp) 10718 call dvmCheckBefore # (dPC, dFP, self) 10719 movl rSELF, %eax 107201: 10721 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10722 jmp *dvmAsmInstructionStart+(89*4) 10723 10724/* ------------------------------ */ 10725.L_ALT_OP_IPUT_WIDE: /* 0x5a */ 10726/* File: x86/alt_stub.S */ 10727/* 10728 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10729 * any interesting requests and then jump to the real instruction 10730 * handler. Unlike the Arm handler, we can't do this as a tail call 10731 * because rIBASE is caller save and we need to reload it. 10732 * 10733 * Note that unlike in the Arm implementation, we should never arrive 10734 * here with a zero breakFlag because we always refresh rIBASE on 10735 * return. 10736 */ 10737 EXPORT_PC 10738 movl rSELF, %eax 10739 movl rPC, OUT_ARG0(%esp) 10740 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10741 movl rFP, OUT_ARG1(%esp) 10742 je 1f # reload rIBASE & resume if not 10743 movl %eax, OUT_ARG2(%esp) 10744 call dvmCheckBefore # (dPC, dFP, self) 10745 movl rSELF, %eax 107461: 10747 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10748 jmp *dvmAsmInstructionStart+(90*4) 10749 10750/* ------------------------------ */ 10751.L_ALT_OP_IPUT_OBJECT: /* 0x5b */ 10752/* File: x86/alt_stub.S */ 10753/* 10754 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10755 * any interesting requests and then jump to the real instruction 10756 * handler. Unlike the Arm handler, we can't do this as a tail call 10757 * because rIBASE is caller save and we need to reload it. 10758 * 10759 * Note that unlike in the Arm implementation, we should never arrive 10760 * here with a zero breakFlag because we always refresh rIBASE on 10761 * return. 10762 */ 10763 EXPORT_PC 10764 movl rSELF, %eax 10765 movl rPC, OUT_ARG0(%esp) 10766 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10767 movl rFP, OUT_ARG1(%esp) 10768 je 1f # reload rIBASE & resume if not 10769 movl %eax, OUT_ARG2(%esp) 10770 call dvmCheckBefore # (dPC, dFP, self) 10771 movl rSELF, %eax 107721: 10773 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10774 jmp *dvmAsmInstructionStart+(91*4) 10775 10776/* ------------------------------ */ 10777.L_ALT_OP_IPUT_BOOLEAN: /* 0x5c */ 10778/* File: x86/alt_stub.S */ 10779/* 10780 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10781 * any interesting requests and then jump to the real instruction 10782 * handler. Unlike the Arm handler, we can't do this as a tail call 10783 * because rIBASE is caller save and we need to reload it. 10784 * 10785 * Note that unlike in the Arm implementation, we should never arrive 10786 * here with a zero breakFlag because we always refresh rIBASE on 10787 * return. 10788 */ 10789 EXPORT_PC 10790 movl rSELF, %eax 10791 movl rPC, OUT_ARG0(%esp) 10792 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10793 movl rFP, OUT_ARG1(%esp) 10794 je 1f # reload rIBASE & resume if not 10795 movl %eax, OUT_ARG2(%esp) 10796 call dvmCheckBefore # (dPC, dFP, self) 10797 movl rSELF, %eax 107981: 10799 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10800 jmp *dvmAsmInstructionStart+(92*4) 10801 10802/* ------------------------------ */ 10803.L_ALT_OP_IPUT_BYTE: /* 0x5d */ 10804/* File: x86/alt_stub.S */ 10805/* 10806 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10807 * any interesting requests and then jump to the real instruction 10808 * handler. Unlike the Arm handler, we can't do this as a tail call 10809 * because rIBASE is caller save and we need to reload it. 10810 * 10811 * Note that unlike in the Arm implementation, we should never arrive 10812 * here with a zero breakFlag because we always refresh rIBASE on 10813 * return. 10814 */ 10815 EXPORT_PC 10816 movl rSELF, %eax 10817 movl rPC, OUT_ARG0(%esp) 10818 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10819 movl rFP, OUT_ARG1(%esp) 10820 je 1f # reload rIBASE & resume if not 10821 movl %eax, OUT_ARG2(%esp) 10822 call dvmCheckBefore # (dPC, dFP, self) 10823 movl rSELF, %eax 108241: 10825 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10826 jmp *dvmAsmInstructionStart+(93*4) 10827 10828/* ------------------------------ */ 10829.L_ALT_OP_IPUT_CHAR: /* 0x5e */ 10830/* File: x86/alt_stub.S */ 10831/* 10832 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10833 * any interesting requests and then jump to the real instruction 10834 * handler. Unlike the Arm handler, we can't do this as a tail call 10835 * because rIBASE is caller save and we need to reload it. 10836 * 10837 * Note that unlike in the Arm implementation, we should never arrive 10838 * here with a zero breakFlag because we always refresh rIBASE on 10839 * return. 10840 */ 10841 EXPORT_PC 10842 movl rSELF, %eax 10843 movl rPC, OUT_ARG0(%esp) 10844 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10845 movl rFP, OUT_ARG1(%esp) 10846 je 1f # reload rIBASE & resume if not 10847 movl %eax, OUT_ARG2(%esp) 10848 call dvmCheckBefore # (dPC, dFP, self) 10849 movl rSELF, %eax 108501: 10851 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10852 jmp *dvmAsmInstructionStart+(94*4) 10853 10854/* ------------------------------ */ 10855.L_ALT_OP_IPUT_SHORT: /* 0x5f */ 10856/* File: x86/alt_stub.S */ 10857/* 10858 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10859 * any interesting requests and then jump to the real instruction 10860 * handler. Unlike the Arm handler, we can't do this as a tail call 10861 * because rIBASE is caller save and we need to reload it. 10862 * 10863 * Note that unlike in the Arm implementation, we should never arrive 10864 * here with a zero breakFlag because we always refresh rIBASE on 10865 * return. 10866 */ 10867 EXPORT_PC 10868 movl rSELF, %eax 10869 movl rPC, OUT_ARG0(%esp) 10870 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10871 movl rFP, OUT_ARG1(%esp) 10872 je 1f # reload rIBASE & resume if not 10873 movl %eax, OUT_ARG2(%esp) 10874 call dvmCheckBefore # (dPC, dFP, self) 10875 movl rSELF, %eax 108761: 10877 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10878 jmp *dvmAsmInstructionStart+(95*4) 10879 10880/* ------------------------------ */ 10881.L_ALT_OP_SGET: /* 0x60 */ 10882/* File: x86/alt_stub.S */ 10883/* 10884 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10885 * any interesting requests and then jump to the real instruction 10886 * handler. Unlike the Arm handler, we can't do this as a tail call 10887 * because rIBASE is caller save and we need to reload it. 10888 * 10889 * Note that unlike in the Arm implementation, we should never arrive 10890 * here with a zero breakFlag because we always refresh rIBASE on 10891 * return. 10892 */ 10893 EXPORT_PC 10894 movl rSELF, %eax 10895 movl rPC, OUT_ARG0(%esp) 10896 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10897 movl rFP, OUT_ARG1(%esp) 10898 je 1f # reload rIBASE & resume if not 10899 movl %eax, OUT_ARG2(%esp) 10900 call dvmCheckBefore # (dPC, dFP, self) 10901 movl rSELF, %eax 109021: 10903 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10904 jmp *dvmAsmInstructionStart+(96*4) 10905 10906/* ------------------------------ */ 10907.L_ALT_OP_SGET_WIDE: /* 0x61 */ 10908/* File: x86/alt_stub.S */ 10909/* 10910 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10911 * any interesting requests and then jump to the real instruction 10912 * handler. Unlike the Arm handler, we can't do this as a tail call 10913 * because rIBASE is caller save and we need to reload it. 10914 * 10915 * Note that unlike in the Arm implementation, we should never arrive 10916 * here with a zero breakFlag because we always refresh rIBASE on 10917 * return. 10918 */ 10919 EXPORT_PC 10920 movl rSELF, %eax 10921 movl rPC, OUT_ARG0(%esp) 10922 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10923 movl rFP, OUT_ARG1(%esp) 10924 je 1f # reload rIBASE & resume if not 10925 movl %eax, OUT_ARG2(%esp) 10926 call dvmCheckBefore # (dPC, dFP, self) 10927 movl rSELF, %eax 109281: 10929 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10930 jmp *dvmAsmInstructionStart+(97*4) 10931 10932/* ------------------------------ */ 10933.L_ALT_OP_SGET_OBJECT: /* 0x62 */ 10934/* File: x86/alt_stub.S */ 10935/* 10936 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10937 * any interesting requests and then jump to the real instruction 10938 * handler. Unlike the Arm handler, we can't do this as a tail call 10939 * because rIBASE is caller save and we need to reload it. 10940 * 10941 * Note that unlike in the Arm implementation, we should never arrive 10942 * here with a zero breakFlag because we always refresh rIBASE on 10943 * return. 10944 */ 10945 EXPORT_PC 10946 movl rSELF, %eax 10947 movl rPC, OUT_ARG0(%esp) 10948 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10949 movl rFP, OUT_ARG1(%esp) 10950 je 1f # reload rIBASE & resume if not 10951 movl %eax, OUT_ARG2(%esp) 10952 call dvmCheckBefore # (dPC, dFP, self) 10953 movl rSELF, %eax 109541: 10955 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10956 jmp *dvmAsmInstructionStart+(98*4) 10957 10958/* ------------------------------ */ 10959.L_ALT_OP_SGET_BOOLEAN: /* 0x63 */ 10960/* File: x86/alt_stub.S */ 10961/* 10962 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10963 * any interesting requests and then jump to the real instruction 10964 * handler. Unlike the Arm handler, we can't do this as a tail call 10965 * because rIBASE is caller save and we need to reload it. 10966 * 10967 * Note that unlike in the Arm implementation, we should never arrive 10968 * here with a zero breakFlag because we always refresh rIBASE on 10969 * return. 10970 */ 10971 EXPORT_PC 10972 movl rSELF, %eax 10973 movl rPC, OUT_ARG0(%esp) 10974 cmpb $0,offThread_breakFlags(%eax) # anything to do? 10975 movl rFP, OUT_ARG1(%esp) 10976 je 1f # reload rIBASE & resume if not 10977 movl %eax, OUT_ARG2(%esp) 10978 call dvmCheckBefore # (dPC, dFP, self) 10979 movl rSELF, %eax 109801: 10981 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 10982 jmp *dvmAsmInstructionStart+(99*4) 10983 10984/* ------------------------------ */ 10985.L_ALT_OP_SGET_BYTE: /* 0x64 */ 10986/* File: x86/alt_stub.S */ 10987/* 10988 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10989 * any interesting requests and then jump to the real instruction 10990 * handler. Unlike the Arm handler, we can't do this as a tail call 10991 * because rIBASE is caller save and we need to reload it. 10992 * 10993 * Note that unlike in the Arm implementation, we should never arrive 10994 * here with a zero breakFlag because we always refresh rIBASE on 10995 * return. 10996 */ 10997 EXPORT_PC 10998 movl rSELF, %eax 10999 movl rPC, OUT_ARG0(%esp) 11000 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11001 movl rFP, OUT_ARG1(%esp) 11002 je 1f # reload rIBASE & resume if not 11003 movl %eax, OUT_ARG2(%esp) 11004 call dvmCheckBefore # (dPC, dFP, self) 11005 movl rSELF, %eax 110061: 11007 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11008 jmp *dvmAsmInstructionStart+(100*4) 11009 11010/* ------------------------------ */ 11011.L_ALT_OP_SGET_CHAR: /* 0x65 */ 11012/* File: x86/alt_stub.S */ 11013/* 11014 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11015 * any interesting requests and then jump to the real instruction 11016 * handler. Unlike the Arm handler, we can't do this as a tail call 11017 * because rIBASE is caller save and we need to reload it. 11018 * 11019 * Note that unlike in the Arm implementation, we should never arrive 11020 * here with a zero breakFlag because we always refresh rIBASE on 11021 * return. 11022 */ 11023 EXPORT_PC 11024 movl rSELF, %eax 11025 movl rPC, OUT_ARG0(%esp) 11026 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11027 movl rFP, OUT_ARG1(%esp) 11028 je 1f # reload rIBASE & resume if not 11029 movl %eax, OUT_ARG2(%esp) 11030 call dvmCheckBefore # (dPC, dFP, self) 11031 movl rSELF, %eax 110321: 11033 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11034 jmp *dvmAsmInstructionStart+(101*4) 11035 11036/* ------------------------------ */ 11037.L_ALT_OP_SGET_SHORT: /* 0x66 */ 11038/* File: x86/alt_stub.S */ 11039/* 11040 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11041 * any interesting requests and then jump to the real instruction 11042 * handler. Unlike the Arm handler, we can't do this as a tail call 11043 * because rIBASE is caller save and we need to reload it. 11044 * 11045 * Note that unlike in the Arm implementation, we should never arrive 11046 * here with a zero breakFlag because we always refresh rIBASE on 11047 * return. 11048 */ 11049 EXPORT_PC 11050 movl rSELF, %eax 11051 movl rPC, OUT_ARG0(%esp) 11052 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11053 movl rFP, OUT_ARG1(%esp) 11054 je 1f # reload rIBASE & resume if not 11055 movl %eax, OUT_ARG2(%esp) 11056 call dvmCheckBefore # (dPC, dFP, self) 11057 movl rSELF, %eax 110581: 11059 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11060 jmp *dvmAsmInstructionStart+(102*4) 11061 11062/* ------------------------------ */ 11063.L_ALT_OP_SPUT: /* 0x67 */ 11064/* File: x86/alt_stub.S */ 11065/* 11066 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11067 * any interesting requests and then jump to the real instruction 11068 * handler. Unlike the Arm handler, we can't do this as a tail call 11069 * because rIBASE is caller save and we need to reload it. 11070 * 11071 * Note that unlike in the Arm implementation, we should never arrive 11072 * here with a zero breakFlag because we always refresh rIBASE on 11073 * return. 11074 */ 11075 EXPORT_PC 11076 movl rSELF, %eax 11077 movl rPC, OUT_ARG0(%esp) 11078 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11079 movl rFP, OUT_ARG1(%esp) 11080 je 1f # reload rIBASE & resume if not 11081 movl %eax, OUT_ARG2(%esp) 11082 call dvmCheckBefore # (dPC, dFP, self) 11083 movl rSELF, %eax 110841: 11085 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11086 jmp *dvmAsmInstructionStart+(103*4) 11087 11088/* ------------------------------ */ 11089.L_ALT_OP_SPUT_WIDE: /* 0x68 */ 11090/* File: x86/alt_stub.S */ 11091/* 11092 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11093 * any interesting requests and then jump to the real instruction 11094 * handler. Unlike the Arm handler, we can't do this as a tail call 11095 * because rIBASE is caller save and we need to reload it. 11096 * 11097 * Note that unlike in the Arm implementation, we should never arrive 11098 * here with a zero breakFlag because we always refresh rIBASE on 11099 * return. 11100 */ 11101 EXPORT_PC 11102 movl rSELF, %eax 11103 movl rPC, OUT_ARG0(%esp) 11104 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11105 movl rFP, OUT_ARG1(%esp) 11106 je 1f # reload rIBASE & resume if not 11107 movl %eax, OUT_ARG2(%esp) 11108 call dvmCheckBefore # (dPC, dFP, self) 11109 movl rSELF, %eax 111101: 11111 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11112 jmp *dvmAsmInstructionStart+(104*4) 11113 11114/* ------------------------------ */ 11115.L_ALT_OP_SPUT_OBJECT: /* 0x69 */ 11116/* File: x86/alt_stub.S */ 11117/* 11118 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11119 * any interesting requests and then jump to the real instruction 11120 * handler. Unlike the Arm handler, we can't do this as a tail call 11121 * because rIBASE is caller save and we need to reload it. 11122 * 11123 * Note that unlike in the Arm implementation, we should never arrive 11124 * here with a zero breakFlag because we always refresh rIBASE on 11125 * return. 11126 */ 11127 EXPORT_PC 11128 movl rSELF, %eax 11129 movl rPC, OUT_ARG0(%esp) 11130 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11131 movl rFP, OUT_ARG1(%esp) 11132 je 1f # reload rIBASE & resume if not 11133 movl %eax, OUT_ARG2(%esp) 11134 call dvmCheckBefore # (dPC, dFP, self) 11135 movl rSELF, %eax 111361: 11137 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11138 jmp *dvmAsmInstructionStart+(105*4) 11139 11140/* ------------------------------ */ 11141.L_ALT_OP_SPUT_BOOLEAN: /* 0x6a */ 11142/* File: x86/alt_stub.S */ 11143/* 11144 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11145 * any interesting requests and then jump to the real instruction 11146 * handler. Unlike the Arm handler, we can't do this as a tail call 11147 * because rIBASE is caller save and we need to reload it. 11148 * 11149 * Note that unlike in the Arm implementation, we should never arrive 11150 * here with a zero breakFlag because we always refresh rIBASE on 11151 * return. 11152 */ 11153 EXPORT_PC 11154 movl rSELF, %eax 11155 movl rPC, OUT_ARG0(%esp) 11156 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11157 movl rFP, OUT_ARG1(%esp) 11158 je 1f # reload rIBASE & resume if not 11159 movl %eax, OUT_ARG2(%esp) 11160 call dvmCheckBefore # (dPC, dFP, self) 11161 movl rSELF, %eax 111621: 11163 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11164 jmp *dvmAsmInstructionStart+(106*4) 11165 11166/* ------------------------------ */ 11167.L_ALT_OP_SPUT_BYTE: /* 0x6b */ 11168/* File: x86/alt_stub.S */ 11169/* 11170 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11171 * any interesting requests and then jump to the real instruction 11172 * handler. Unlike the Arm handler, we can't do this as a tail call 11173 * because rIBASE is caller save and we need to reload it. 11174 * 11175 * Note that unlike in the Arm implementation, we should never arrive 11176 * here with a zero breakFlag because we always refresh rIBASE on 11177 * return. 11178 */ 11179 EXPORT_PC 11180 movl rSELF, %eax 11181 movl rPC, OUT_ARG0(%esp) 11182 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11183 movl rFP, OUT_ARG1(%esp) 11184 je 1f # reload rIBASE & resume if not 11185 movl %eax, OUT_ARG2(%esp) 11186 call dvmCheckBefore # (dPC, dFP, self) 11187 movl rSELF, %eax 111881: 11189 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11190 jmp *dvmAsmInstructionStart+(107*4) 11191 11192/* ------------------------------ */ 11193.L_ALT_OP_SPUT_CHAR: /* 0x6c */ 11194/* File: x86/alt_stub.S */ 11195/* 11196 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11197 * any interesting requests and then jump to the real instruction 11198 * handler. Unlike the Arm handler, we can't do this as a tail call 11199 * because rIBASE is caller save and we need to reload it. 11200 * 11201 * Note that unlike in the Arm implementation, we should never arrive 11202 * here with a zero breakFlag because we always refresh rIBASE on 11203 * return. 11204 */ 11205 EXPORT_PC 11206 movl rSELF, %eax 11207 movl rPC, OUT_ARG0(%esp) 11208 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11209 movl rFP, OUT_ARG1(%esp) 11210 je 1f # reload rIBASE & resume if not 11211 movl %eax, OUT_ARG2(%esp) 11212 call dvmCheckBefore # (dPC, dFP, self) 11213 movl rSELF, %eax 112141: 11215 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11216 jmp *dvmAsmInstructionStart+(108*4) 11217 11218/* ------------------------------ */ 11219.L_ALT_OP_SPUT_SHORT: /* 0x6d */ 11220/* File: x86/alt_stub.S */ 11221/* 11222 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11223 * any interesting requests and then jump to the real instruction 11224 * handler. Unlike the Arm handler, we can't do this as a tail call 11225 * because rIBASE is caller save and we need to reload it. 11226 * 11227 * Note that unlike in the Arm implementation, we should never arrive 11228 * here with a zero breakFlag because we always refresh rIBASE on 11229 * return. 11230 */ 11231 EXPORT_PC 11232 movl rSELF, %eax 11233 movl rPC, OUT_ARG0(%esp) 11234 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11235 movl rFP, OUT_ARG1(%esp) 11236 je 1f # reload rIBASE & resume if not 11237 movl %eax, OUT_ARG2(%esp) 11238 call dvmCheckBefore # (dPC, dFP, self) 11239 movl rSELF, %eax 112401: 11241 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11242 jmp *dvmAsmInstructionStart+(109*4) 11243 11244/* ------------------------------ */ 11245.L_ALT_OP_INVOKE_VIRTUAL: /* 0x6e */ 11246/* File: x86/alt_stub.S */ 11247/* 11248 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11249 * any interesting requests and then jump to the real instruction 11250 * handler. Unlike the Arm handler, we can't do this as a tail call 11251 * because rIBASE is caller save and we need to reload it. 11252 * 11253 * Note that unlike in the Arm implementation, we should never arrive 11254 * here with a zero breakFlag because we always refresh rIBASE on 11255 * return. 11256 */ 11257 EXPORT_PC 11258 movl rSELF, %eax 11259 movl rPC, OUT_ARG0(%esp) 11260 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11261 movl rFP, OUT_ARG1(%esp) 11262 je 1f # reload rIBASE & resume if not 11263 movl %eax, OUT_ARG2(%esp) 11264 call dvmCheckBefore # (dPC, dFP, self) 11265 movl rSELF, %eax 112661: 11267 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11268 jmp *dvmAsmInstructionStart+(110*4) 11269 11270/* ------------------------------ */ 11271.L_ALT_OP_INVOKE_SUPER: /* 0x6f */ 11272/* File: x86/alt_stub.S */ 11273/* 11274 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11275 * any interesting requests and then jump to the real instruction 11276 * handler. Unlike the Arm handler, we can't do this as a tail call 11277 * because rIBASE is caller save and we need to reload it. 11278 * 11279 * Note that unlike in the Arm implementation, we should never arrive 11280 * here with a zero breakFlag because we always refresh rIBASE on 11281 * return. 11282 */ 11283 EXPORT_PC 11284 movl rSELF, %eax 11285 movl rPC, OUT_ARG0(%esp) 11286 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11287 movl rFP, OUT_ARG1(%esp) 11288 je 1f # reload rIBASE & resume if not 11289 movl %eax, OUT_ARG2(%esp) 11290 call dvmCheckBefore # (dPC, dFP, self) 11291 movl rSELF, %eax 112921: 11293 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11294 jmp *dvmAsmInstructionStart+(111*4) 11295 11296/* ------------------------------ */ 11297.L_ALT_OP_INVOKE_DIRECT: /* 0x70 */ 11298/* File: x86/alt_stub.S */ 11299/* 11300 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11301 * any interesting requests and then jump to the real instruction 11302 * handler. Unlike the Arm handler, we can't do this as a tail call 11303 * because rIBASE is caller save and we need to reload it. 11304 * 11305 * Note that unlike in the Arm implementation, we should never arrive 11306 * here with a zero breakFlag because we always refresh rIBASE on 11307 * return. 11308 */ 11309 EXPORT_PC 11310 movl rSELF, %eax 11311 movl rPC, OUT_ARG0(%esp) 11312 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11313 movl rFP, OUT_ARG1(%esp) 11314 je 1f # reload rIBASE & resume if not 11315 movl %eax, OUT_ARG2(%esp) 11316 call dvmCheckBefore # (dPC, dFP, self) 11317 movl rSELF, %eax 113181: 11319 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11320 jmp *dvmAsmInstructionStart+(112*4) 11321 11322/* ------------------------------ */ 11323.L_ALT_OP_INVOKE_STATIC: /* 0x71 */ 11324/* File: x86/alt_stub.S */ 11325/* 11326 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11327 * any interesting requests and then jump to the real instruction 11328 * handler. Unlike the Arm handler, we can't do this as a tail call 11329 * because rIBASE is caller save and we need to reload it. 11330 * 11331 * Note that unlike in the Arm implementation, we should never arrive 11332 * here with a zero breakFlag because we always refresh rIBASE on 11333 * return. 11334 */ 11335 EXPORT_PC 11336 movl rSELF, %eax 11337 movl rPC, OUT_ARG0(%esp) 11338 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11339 movl rFP, OUT_ARG1(%esp) 11340 je 1f # reload rIBASE & resume if not 11341 movl %eax, OUT_ARG2(%esp) 11342 call dvmCheckBefore # (dPC, dFP, self) 11343 movl rSELF, %eax 113441: 11345 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11346 jmp *dvmAsmInstructionStart+(113*4) 11347 11348/* ------------------------------ */ 11349.L_ALT_OP_INVOKE_INTERFACE: /* 0x72 */ 11350/* File: x86/alt_stub.S */ 11351/* 11352 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11353 * any interesting requests and then jump to the real instruction 11354 * handler. Unlike the Arm handler, we can't do this as a tail call 11355 * because rIBASE is caller save and we need to reload it. 11356 * 11357 * Note that unlike in the Arm implementation, we should never arrive 11358 * here with a zero breakFlag because we always refresh rIBASE on 11359 * return. 11360 */ 11361 EXPORT_PC 11362 movl rSELF, %eax 11363 movl rPC, OUT_ARG0(%esp) 11364 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11365 movl rFP, OUT_ARG1(%esp) 11366 je 1f # reload rIBASE & resume if not 11367 movl %eax, OUT_ARG2(%esp) 11368 call dvmCheckBefore # (dPC, dFP, self) 11369 movl rSELF, %eax 113701: 11371 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11372 jmp *dvmAsmInstructionStart+(114*4) 11373 11374/* ------------------------------ */ 11375.L_ALT_OP_UNUSED_73: /* 0x73 */ 11376/* File: x86/alt_stub.S */ 11377/* 11378 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11379 * any interesting requests and then jump to the real instruction 11380 * handler. Unlike the Arm handler, we can't do this as a tail call 11381 * because rIBASE is caller save and we need to reload it. 11382 * 11383 * Note that unlike in the Arm implementation, we should never arrive 11384 * here with a zero breakFlag because we always refresh rIBASE on 11385 * return. 11386 */ 11387 EXPORT_PC 11388 movl rSELF, %eax 11389 movl rPC, OUT_ARG0(%esp) 11390 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11391 movl rFP, OUT_ARG1(%esp) 11392 je 1f # reload rIBASE & resume if not 11393 movl %eax, OUT_ARG2(%esp) 11394 call dvmCheckBefore # (dPC, dFP, self) 11395 movl rSELF, %eax 113961: 11397 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11398 jmp *dvmAsmInstructionStart+(115*4) 11399 11400/* ------------------------------ */ 11401.L_ALT_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 11402/* File: x86/alt_stub.S */ 11403/* 11404 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11405 * any interesting requests and then jump to the real instruction 11406 * handler. Unlike the Arm handler, we can't do this as a tail call 11407 * because rIBASE is caller save and we need to reload it. 11408 * 11409 * Note that unlike in the Arm implementation, we should never arrive 11410 * here with a zero breakFlag because we always refresh rIBASE on 11411 * return. 11412 */ 11413 EXPORT_PC 11414 movl rSELF, %eax 11415 movl rPC, OUT_ARG0(%esp) 11416 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11417 movl rFP, OUT_ARG1(%esp) 11418 je 1f # reload rIBASE & resume if not 11419 movl %eax, OUT_ARG2(%esp) 11420 call dvmCheckBefore # (dPC, dFP, self) 11421 movl rSELF, %eax 114221: 11423 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11424 jmp *dvmAsmInstructionStart+(116*4) 11425 11426/* ------------------------------ */ 11427.L_ALT_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 11428/* File: x86/alt_stub.S */ 11429/* 11430 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11431 * any interesting requests and then jump to the real instruction 11432 * handler. Unlike the Arm handler, we can't do this as a tail call 11433 * because rIBASE is caller save and we need to reload it. 11434 * 11435 * Note that unlike in the Arm implementation, we should never arrive 11436 * here with a zero breakFlag because we always refresh rIBASE on 11437 * return. 11438 */ 11439 EXPORT_PC 11440 movl rSELF, %eax 11441 movl rPC, OUT_ARG0(%esp) 11442 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11443 movl rFP, OUT_ARG1(%esp) 11444 je 1f # reload rIBASE & resume if not 11445 movl %eax, OUT_ARG2(%esp) 11446 call dvmCheckBefore # (dPC, dFP, self) 11447 movl rSELF, %eax 114481: 11449 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11450 jmp *dvmAsmInstructionStart+(117*4) 11451 11452/* ------------------------------ */ 11453.L_ALT_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 11454/* File: x86/alt_stub.S */ 11455/* 11456 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11457 * any interesting requests and then jump to the real instruction 11458 * handler. Unlike the Arm handler, we can't do this as a tail call 11459 * because rIBASE is caller save and we need to reload it. 11460 * 11461 * Note that unlike in the Arm implementation, we should never arrive 11462 * here with a zero breakFlag because we always refresh rIBASE on 11463 * return. 11464 */ 11465 EXPORT_PC 11466 movl rSELF, %eax 11467 movl rPC, OUT_ARG0(%esp) 11468 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11469 movl rFP, OUT_ARG1(%esp) 11470 je 1f # reload rIBASE & resume if not 11471 movl %eax, OUT_ARG2(%esp) 11472 call dvmCheckBefore # (dPC, dFP, self) 11473 movl rSELF, %eax 114741: 11475 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11476 jmp *dvmAsmInstructionStart+(118*4) 11477 11478/* ------------------------------ */ 11479.L_ALT_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 11480/* File: x86/alt_stub.S */ 11481/* 11482 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11483 * any interesting requests and then jump to the real instruction 11484 * handler. Unlike the Arm handler, we can't do this as a tail call 11485 * because rIBASE is caller save and we need to reload it. 11486 * 11487 * Note that unlike in the Arm implementation, we should never arrive 11488 * here with a zero breakFlag because we always refresh rIBASE on 11489 * return. 11490 */ 11491 EXPORT_PC 11492 movl rSELF, %eax 11493 movl rPC, OUT_ARG0(%esp) 11494 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11495 movl rFP, OUT_ARG1(%esp) 11496 je 1f # reload rIBASE & resume if not 11497 movl %eax, OUT_ARG2(%esp) 11498 call dvmCheckBefore # (dPC, dFP, self) 11499 movl rSELF, %eax 115001: 11501 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11502 jmp *dvmAsmInstructionStart+(119*4) 11503 11504/* ------------------------------ */ 11505.L_ALT_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 11506/* File: x86/alt_stub.S */ 11507/* 11508 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11509 * any interesting requests and then jump to the real instruction 11510 * handler. Unlike the Arm handler, we can't do this as a tail call 11511 * because rIBASE is caller save and we need to reload it. 11512 * 11513 * Note that unlike in the Arm implementation, we should never arrive 11514 * here with a zero breakFlag because we always refresh rIBASE on 11515 * return. 11516 */ 11517 EXPORT_PC 11518 movl rSELF, %eax 11519 movl rPC, OUT_ARG0(%esp) 11520 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11521 movl rFP, OUT_ARG1(%esp) 11522 je 1f # reload rIBASE & resume if not 11523 movl %eax, OUT_ARG2(%esp) 11524 call dvmCheckBefore # (dPC, dFP, self) 11525 movl rSELF, %eax 115261: 11527 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11528 jmp *dvmAsmInstructionStart+(120*4) 11529 11530/* ------------------------------ */ 11531.L_ALT_OP_UNUSED_79: /* 0x79 */ 11532/* File: x86/alt_stub.S */ 11533/* 11534 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11535 * any interesting requests and then jump to the real instruction 11536 * handler. Unlike the Arm handler, we can't do this as a tail call 11537 * because rIBASE is caller save and we need to reload it. 11538 * 11539 * Note that unlike in the Arm implementation, we should never arrive 11540 * here with a zero breakFlag because we always refresh rIBASE on 11541 * return. 11542 */ 11543 EXPORT_PC 11544 movl rSELF, %eax 11545 movl rPC, OUT_ARG0(%esp) 11546 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11547 movl rFP, OUT_ARG1(%esp) 11548 je 1f # reload rIBASE & resume if not 11549 movl %eax, OUT_ARG2(%esp) 11550 call dvmCheckBefore # (dPC, dFP, self) 11551 movl rSELF, %eax 115521: 11553 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11554 jmp *dvmAsmInstructionStart+(121*4) 11555 11556/* ------------------------------ */ 11557.L_ALT_OP_UNUSED_7A: /* 0x7a */ 11558/* File: x86/alt_stub.S */ 11559/* 11560 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11561 * any interesting requests and then jump to the real instruction 11562 * handler. Unlike the Arm handler, we can't do this as a tail call 11563 * because rIBASE is caller save and we need to reload it. 11564 * 11565 * Note that unlike in the Arm implementation, we should never arrive 11566 * here with a zero breakFlag because we always refresh rIBASE on 11567 * return. 11568 */ 11569 EXPORT_PC 11570 movl rSELF, %eax 11571 movl rPC, OUT_ARG0(%esp) 11572 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11573 movl rFP, OUT_ARG1(%esp) 11574 je 1f # reload rIBASE & resume if not 11575 movl %eax, OUT_ARG2(%esp) 11576 call dvmCheckBefore # (dPC, dFP, self) 11577 movl rSELF, %eax 115781: 11579 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11580 jmp *dvmAsmInstructionStart+(122*4) 11581 11582/* ------------------------------ */ 11583.L_ALT_OP_NEG_INT: /* 0x7b */ 11584/* File: x86/alt_stub.S */ 11585/* 11586 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11587 * any interesting requests and then jump to the real instruction 11588 * handler. Unlike the Arm handler, we can't do this as a tail call 11589 * because rIBASE is caller save and we need to reload it. 11590 * 11591 * Note that unlike in the Arm implementation, we should never arrive 11592 * here with a zero breakFlag because we always refresh rIBASE on 11593 * return. 11594 */ 11595 EXPORT_PC 11596 movl rSELF, %eax 11597 movl rPC, OUT_ARG0(%esp) 11598 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11599 movl rFP, OUT_ARG1(%esp) 11600 je 1f # reload rIBASE & resume if not 11601 movl %eax, OUT_ARG2(%esp) 11602 call dvmCheckBefore # (dPC, dFP, self) 11603 movl rSELF, %eax 116041: 11605 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11606 jmp *dvmAsmInstructionStart+(123*4) 11607 11608/* ------------------------------ */ 11609.L_ALT_OP_NOT_INT: /* 0x7c */ 11610/* File: x86/alt_stub.S */ 11611/* 11612 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11613 * any interesting requests and then jump to the real instruction 11614 * handler. Unlike the Arm handler, we can't do this as a tail call 11615 * because rIBASE is caller save and we need to reload it. 11616 * 11617 * Note that unlike in the Arm implementation, we should never arrive 11618 * here with a zero breakFlag because we always refresh rIBASE on 11619 * return. 11620 */ 11621 EXPORT_PC 11622 movl rSELF, %eax 11623 movl rPC, OUT_ARG0(%esp) 11624 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11625 movl rFP, OUT_ARG1(%esp) 11626 je 1f # reload rIBASE & resume if not 11627 movl %eax, OUT_ARG2(%esp) 11628 call dvmCheckBefore # (dPC, dFP, self) 11629 movl rSELF, %eax 116301: 11631 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11632 jmp *dvmAsmInstructionStart+(124*4) 11633 11634/* ------------------------------ */ 11635.L_ALT_OP_NEG_LONG: /* 0x7d */ 11636/* File: x86/alt_stub.S */ 11637/* 11638 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11639 * any interesting requests and then jump to the real instruction 11640 * handler. Unlike the Arm handler, we can't do this as a tail call 11641 * because rIBASE is caller save and we need to reload it. 11642 * 11643 * Note that unlike in the Arm implementation, we should never arrive 11644 * here with a zero breakFlag because we always refresh rIBASE on 11645 * return. 11646 */ 11647 EXPORT_PC 11648 movl rSELF, %eax 11649 movl rPC, OUT_ARG0(%esp) 11650 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11651 movl rFP, OUT_ARG1(%esp) 11652 je 1f # reload rIBASE & resume if not 11653 movl %eax, OUT_ARG2(%esp) 11654 call dvmCheckBefore # (dPC, dFP, self) 11655 movl rSELF, %eax 116561: 11657 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11658 jmp *dvmAsmInstructionStart+(125*4) 11659 11660/* ------------------------------ */ 11661.L_ALT_OP_NOT_LONG: /* 0x7e */ 11662/* File: x86/alt_stub.S */ 11663/* 11664 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11665 * any interesting requests and then jump to the real instruction 11666 * handler. Unlike the Arm handler, we can't do this as a tail call 11667 * because rIBASE is caller save and we need to reload it. 11668 * 11669 * Note that unlike in the Arm implementation, we should never arrive 11670 * here with a zero breakFlag because we always refresh rIBASE on 11671 * return. 11672 */ 11673 EXPORT_PC 11674 movl rSELF, %eax 11675 movl rPC, OUT_ARG0(%esp) 11676 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11677 movl rFP, OUT_ARG1(%esp) 11678 je 1f # reload rIBASE & resume if not 11679 movl %eax, OUT_ARG2(%esp) 11680 call dvmCheckBefore # (dPC, dFP, self) 11681 movl rSELF, %eax 116821: 11683 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11684 jmp *dvmAsmInstructionStart+(126*4) 11685 11686/* ------------------------------ */ 11687.L_ALT_OP_NEG_FLOAT: /* 0x7f */ 11688/* File: x86/alt_stub.S */ 11689/* 11690 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11691 * any interesting requests and then jump to the real instruction 11692 * handler. Unlike the Arm handler, we can't do this as a tail call 11693 * because rIBASE is caller save and we need to reload it. 11694 * 11695 * Note that unlike in the Arm implementation, we should never arrive 11696 * here with a zero breakFlag because we always refresh rIBASE on 11697 * return. 11698 */ 11699 EXPORT_PC 11700 movl rSELF, %eax 11701 movl rPC, OUT_ARG0(%esp) 11702 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11703 movl rFP, OUT_ARG1(%esp) 11704 je 1f # reload rIBASE & resume if not 11705 movl %eax, OUT_ARG2(%esp) 11706 call dvmCheckBefore # (dPC, dFP, self) 11707 movl rSELF, %eax 117081: 11709 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11710 jmp *dvmAsmInstructionStart+(127*4) 11711 11712/* ------------------------------ */ 11713.L_ALT_OP_NEG_DOUBLE: /* 0x80 */ 11714/* File: x86/alt_stub.S */ 11715/* 11716 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11717 * any interesting requests and then jump to the real instruction 11718 * handler. Unlike the Arm handler, we can't do this as a tail call 11719 * because rIBASE is caller save and we need to reload it. 11720 * 11721 * Note that unlike in the Arm implementation, we should never arrive 11722 * here with a zero breakFlag because we always refresh rIBASE on 11723 * return. 11724 */ 11725 EXPORT_PC 11726 movl rSELF, %eax 11727 movl rPC, OUT_ARG0(%esp) 11728 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11729 movl rFP, OUT_ARG1(%esp) 11730 je 1f # reload rIBASE & resume if not 11731 movl %eax, OUT_ARG2(%esp) 11732 call dvmCheckBefore # (dPC, dFP, self) 11733 movl rSELF, %eax 117341: 11735 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11736 jmp *dvmAsmInstructionStart+(128*4) 11737 11738/* ------------------------------ */ 11739.L_ALT_OP_INT_TO_LONG: /* 0x81 */ 11740/* File: x86/alt_stub.S */ 11741/* 11742 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11743 * any interesting requests and then jump to the real instruction 11744 * handler. Unlike the Arm handler, we can't do this as a tail call 11745 * because rIBASE is caller save and we need to reload it. 11746 * 11747 * Note that unlike in the Arm implementation, we should never arrive 11748 * here with a zero breakFlag because we always refresh rIBASE on 11749 * return. 11750 */ 11751 EXPORT_PC 11752 movl rSELF, %eax 11753 movl rPC, OUT_ARG0(%esp) 11754 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11755 movl rFP, OUT_ARG1(%esp) 11756 je 1f # reload rIBASE & resume if not 11757 movl %eax, OUT_ARG2(%esp) 11758 call dvmCheckBefore # (dPC, dFP, self) 11759 movl rSELF, %eax 117601: 11761 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11762 jmp *dvmAsmInstructionStart+(129*4) 11763 11764/* ------------------------------ */ 11765.L_ALT_OP_INT_TO_FLOAT: /* 0x82 */ 11766/* File: x86/alt_stub.S */ 11767/* 11768 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11769 * any interesting requests and then jump to the real instruction 11770 * handler. Unlike the Arm handler, we can't do this as a tail call 11771 * because rIBASE is caller save and we need to reload it. 11772 * 11773 * Note that unlike in the Arm implementation, we should never arrive 11774 * here with a zero breakFlag because we always refresh rIBASE on 11775 * return. 11776 */ 11777 EXPORT_PC 11778 movl rSELF, %eax 11779 movl rPC, OUT_ARG0(%esp) 11780 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11781 movl rFP, OUT_ARG1(%esp) 11782 je 1f # reload rIBASE & resume if not 11783 movl %eax, OUT_ARG2(%esp) 11784 call dvmCheckBefore # (dPC, dFP, self) 11785 movl rSELF, %eax 117861: 11787 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11788 jmp *dvmAsmInstructionStart+(130*4) 11789 11790/* ------------------------------ */ 11791.L_ALT_OP_INT_TO_DOUBLE: /* 0x83 */ 11792/* File: x86/alt_stub.S */ 11793/* 11794 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11795 * any interesting requests and then jump to the real instruction 11796 * handler. Unlike the Arm handler, we can't do this as a tail call 11797 * because rIBASE is caller save and we need to reload it. 11798 * 11799 * Note that unlike in the Arm implementation, we should never arrive 11800 * here with a zero breakFlag because we always refresh rIBASE on 11801 * return. 11802 */ 11803 EXPORT_PC 11804 movl rSELF, %eax 11805 movl rPC, OUT_ARG0(%esp) 11806 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11807 movl rFP, OUT_ARG1(%esp) 11808 je 1f # reload rIBASE & resume if not 11809 movl %eax, OUT_ARG2(%esp) 11810 call dvmCheckBefore # (dPC, dFP, self) 11811 movl rSELF, %eax 118121: 11813 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11814 jmp *dvmAsmInstructionStart+(131*4) 11815 11816/* ------------------------------ */ 11817.L_ALT_OP_LONG_TO_INT: /* 0x84 */ 11818/* File: x86/alt_stub.S */ 11819/* 11820 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11821 * any interesting requests and then jump to the real instruction 11822 * handler. Unlike the Arm handler, we can't do this as a tail call 11823 * because rIBASE is caller save and we need to reload it. 11824 * 11825 * Note that unlike in the Arm implementation, we should never arrive 11826 * here with a zero breakFlag because we always refresh rIBASE on 11827 * return. 11828 */ 11829 EXPORT_PC 11830 movl rSELF, %eax 11831 movl rPC, OUT_ARG0(%esp) 11832 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11833 movl rFP, OUT_ARG1(%esp) 11834 je 1f # reload rIBASE & resume if not 11835 movl %eax, OUT_ARG2(%esp) 11836 call dvmCheckBefore # (dPC, dFP, self) 11837 movl rSELF, %eax 118381: 11839 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11840 jmp *dvmAsmInstructionStart+(132*4) 11841 11842/* ------------------------------ */ 11843.L_ALT_OP_LONG_TO_FLOAT: /* 0x85 */ 11844/* File: x86/alt_stub.S */ 11845/* 11846 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11847 * any interesting requests and then jump to the real instruction 11848 * handler. Unlike the Arm handler, we can't do this as a tail call 11849 * because rIBASE is caller save and we need to reload it. 11850 * 11851 * Note that unlike in the Arm implementation, we should never arrive 11852 * here with a zero breakFlag because we always refresh rIBASE on 11853 * return. 11854 */ 11855 EXPORT_PC 11856 movl rSELF, %eax 11857 movl rPC, OUT_ARG0(%esp) 11858 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11859 movl rFP, OUT_ARG1(%esp) 11860 je 1f # reload rIBASE & resume if not 11861 movl %eax, OUT_ARG2(%esp) 11862 call dvmCheckBefore # (dPC, dFP, self) 11863 movl rSELF, %eax 118641: 11865 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11866 jmp *dvmAsmInstructionStart+(133*4) 11867 11868/* ------------------------------ */ 11869.L_ALT_OP_LONG_TO_DOUBLE: /* 0x86 */ 11870/* File: x86/alt_stub.S */ 11871/* 11872 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11873 * any interesting requests and then jump to the real instruction 11874 * handler. Unlike the Arm handler, we can't do this as a tail call 11875 * because rIBASE is caller save and we need to reload it. 11876 * 11877 * Note that unlike in the Arm implementation, we should never arrive 11878 * here with a zero breakFlag because we always refresh rIBASE on 11879 * return. 11880 */ 11881 EXPORT_PC 11882 movl rSELF, %eax 11883 movl rPC, OUT_ARG0(%esp) 11884 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11885 movl rFP, OUT_ARG1(%esp) 11886 je 1f # reload rIBASE & resume if not 11887 movl %eax, OUT_ARG2(%esp) 11888 call dvmCheckBefore # (dPC, dFP, self) 11889 movl rSELF, %eax 118901: 11891 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11892 jmp *dvmAsmInstructionStart+(134*4) 11893 11894/* ------------------------------ */ 11895.L_ALT_OP_FLOAT_TO_INT: /* 0x87 */ 11896/* File: x86/alt_stub.S */ 11897/* 11898 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11899 * any interesting requests and then jump to the real instruction 11900 * handler. Unlike the Arm handler, we can't do this as a tail call 11901 * because rIBASE is caller save and we need to reload it. 11902 * 11903 * Note that unlike in the Arm implementation, we should never arrive 11904 * here with a zero breakFlag because we always refresh rIBASE on 11905 * return. 11906 */ 11907 EXPORT_PC 11908 movl rSELF, %eax 11909 movl rPC, OUT_ARG0(%esp) 11910 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11911 movl rFP, OUT_ARG1(%esp) 11912 je 1f # reload rIBASE & resume if not 11913 movl %eax, OUT_ARG2(%esp) 11914 call dvmCheckBefore # (dPC, dFP, self) 11915 movl rSELF, %eax 119161: 11917 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11918 jmp *dvmAsmInstructionStart+(135*4) 11919 11920/* ------------------------------ */ 11921.L_ALT_OP_FLOAT_TO_LONG: /* 0x88 */ 11922/* File: x86/alt_stub.S */ 11923/* 11924 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11925 * any interesting requests and then jump to the real instruction 11926 * handler. Unlike the Arm handler, we can't do this as a tail call 11927 * because rIBASE is caller save and we need to reload it. 11928 * 11929 * Note that unlike in the Arm implementation, we should never arrive 11930 * here with a zero breakFlag because we always refresh rIBASE on 11931 * return. 11932 */ 11933 EXPORT_PC 11934 movl rSELF, %eax 11935 movl rPC, OUT_ARG0(%esp) 11936 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11937 movl rFP, OUT_ARG1(%esp) 11938 je 1f # reload rIBASE & resume if not 11939 movl %eax, OUT_ARG2(%esp) 11940 call dvmCheckBefore # (dPC, dFP, self) 11941 movl rSELF, %eax 119421: 11943 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11944 jmp *dvmAsmInstructionStart+(136*4) 11945 11946/* ------------------------------ */ 11947.L_ALT_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 11948/* File: x86/alt_stub.S */ 11949/* 11950 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11951 * any interesting requests and then jump to the real instruction 11952 * handler. Unlike the Arm handler, we can't do this as a tail call 11953 * because rIBASE is caller save and we need to reload it. 11954 * 11955 * Note that unlike in the Arm implementation, we should never arrive 11956 * here with a zero breakFlag because we always refresh rIBASE on 11957 * return. 11958 */ 11959 EXPORT_PC 11960 movl rSELF, %eax 11961 movl rPC, OUT_ARG0(%esp) 11962 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11963 movl rFP, OUT_ARG1(%esp) 11964 je 1f # reload rIBASE & resume if not 11965 movl %eax, OUT_ARG2(%esp) 11966 call dvmCheckBefore # (dPC, dFP, self) 11967 movl rSELF, %eax 119681: 11969 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11970 jmp *dvmAsmInstructionStart+(137*4) 11971 11972/* ------------------------------ */ 11973.L_ALT_OP_DOUBLE_TO_INT: /* 0x8a */ 11974/* File: x86/alt_stub.S */ 11975/* 11976 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11977 * any interesting requests and then jump to the real instruction 11978 * handler. Unlike the Arm handler, we can't do this as a tail call 11979 * because rIBASE is caller save and we need to reload it. 11980 * 11981 * Note that unlike in the Arm implementation, we should never arrive 11982 * here with a zero breakFlag because we always refresh rIBASE on 11983 * return. 11984 */ 11985 EXPORT_PC 11986 movl rSELF, %eax 11987 movl rPC, OUT_ARG0(%esp) 11988 cmpb $0,offThread_breakFlags(%eax) # anything to do? 11989 movl rFP, OUT_ARG1(%esp) 11990 je 1f # reload rIBASE & resume if not 11991 movl %eax, OUT_ARG2(%esp) 11992 call dvmCheckBefore # (dPC, dFP, self) 11993 movl rSELF, %eax 119941: 11995 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 11996 jmp *dvmAsmInstructionStart+(138*4) 11997 11998/* ------------------------------ */ 11999.L_ALT_OP_DOUBLE_TO_LONG: /* 0x8b */ 12000/* File: x86/alt_stub.S */ 12001/* 12002 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12003 * any interesting requests and then jump to the real instruction 12004 * handler. Unlike the Arm handler, we can't do this as a tail call 12005 * because rIBASE is caller save and we need to reload it. 12006 * 12007 * Note that unlike in the Arm implementation, we should never arrive 12008 * here with a zero breakFlag because we always refresh rIBASE on 12009 * return. 12010 */ 12011 EXPORT_PC 12012 movl rSELF, %eax 12013 movl rPC, OUT_ARG0(%esp) 12014 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12015 movl rFP, OUT_ARG1(%esp) 12016 je 1f # reload rIBASE & resume if not 12017 movl %eax, OUT_ARG2(%esp) 12018 call dvmCheckBefore # (dPC, dFP, self) 12019 movl rSELF, %eax 120201: 12021 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12022 jmp *dvmAsmInstructionStart+(139*4) 12023 12024/* ------------------------------ */ 12025.L_ALT_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 12026/* File: x86/alt_stub.S */ 12027/* 12028 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12029 * any interesting requests and then jump to the real instruction 12030 * handler. Unlike the Arm handler, we can't do this as a tail call 12031 * because rIBASE is caller save and we need to reload it. 12032 * 12033 * Note that unlike in the Arm implementation, we should never arrive 12034 * here with a zero breakFlag because we always refresh rIBASE on 12035 * return. 12036 */ 12037 EXPORT_PC 12038 movl rSELF, %eax 12039 movl rPC, OUT_ARG0(%esp) 12040 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12041 movl rFP, OUT_ARG1(%esp) 12042 je 1f # reload rIBASE & resume if not 12043 movl %eax, OUT_ARG2(%esp) 12044 call dvmCheckBefore # (dPC, dFP, self) 12045 movl rSELF, %eax 120461: 12047 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12048 jmp *dvmAsmInstructionStart+(140*4) 12049 12050/* ------------------------------ */ 12051.L_ALT_OP_INT_TO_BYTE: /* 0x8d */ 12052/* File: x86/alt_stub.S */ 12053/* 12054 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12055 * any interesting requests and then jump to the real instruction 12056 * handler. Unlike the Arm handler, we can't do this as a tail call 12057 * because rIBASE is caller save and we need to reload it. 12058 * 12059 * Note that unlike in the Arm implementation, we should never arrive 12060 * here with a zero breakFlag because we always refresh rIBASE on 12061 * return. 12062 */ 12063 EXPORT_PC 12064 movl rSELF, %eax 12065 movl rPC, OUT_ARG0(%esp) 12066 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12067 movl rFP, OUT_ARG1(%esp) 12068 je 1f # reload rIBASE & resume if not 12069 movl %eax, OUT_ARG2(%esp) 12070 call dvmCheckBefore # (dPC, dFP, self) 12071 movl rSELF, %eax 120721: 12073 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12074 jmp *dvmAsmInstructionStart+(141*4) 12075 12076/* ------------------------------ */ 12077.L_ALT_OP_INT_TO_CHAR: /* 0x8e */ 12078/* File: x86/alt_stub.S */ 12079/* 12080 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12081 * any interesting requests and then jump to the real instruction 12082 * handler. Unlike the Arm handler, we can't do this as a tail call 12083 * because rIBASE is caller save and we need to reload it. 12084 * 12085 * Note that unlike in the Arm implementation, we should never arrive 12086 * here with a zero breakFlag because we always refresh rIBASE on 12087 * return. 12088 */ 12089 EXPORT_PC 12090 movl rSELF, %eax 12091 movl rPC, OUT_ARG0(%esp) 12092 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12093 movl rFP, OUT_ARG1(%esp) 12094 je 1f # reload rIBASE & resume if not 12095 movl %eax, OUT_ARG2(%esp) 12096 call dvmCheckBefore # (dPC, dFP, self) 12097 movl rSELF, %eax 120981: 12099 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12100 jmp *dvmAsmInstructionStart+(142*4) 12101 12102/* ------------------------------ */ 12103.L_ALT_OP_INT_TO_SHORT: /* 0x8f */ 12104/* File: x86/alt_stub.S */ 12105/* 12106 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12107 * any interesting requests and then jump to the real instruction 12108 * handler. Unlike the Arm handler, we can't do this as a tail call 12109 * because rIBASE is caller save and we need to reload it. 12110 * 12111 * Note that unlike in the Arm implementation, we should never arrive 12112 * here with a zero breakFlag because we always refresh rIBASE on 12113 * return. 12114 */ 12115 EXPORT_PC 12116 movl rSELF, %eax 12117 movl rPC, OUT_ARG0(%esp) 12118 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12119 movl rFP, OUT_ARG1(%esp) 12120 je 1f # reload rIBASE & resume if not 12121 movl %eax, OUT_ARG2(%esp) 12122 call dvmCheckBefore # (dPC, dFP, self) 12123 movl rSELF, %eax 121241: 12125 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12126 jmp *dvmAsmInstructionStart+(143*4) 12127 12128/* ------------------------------ */ 12129.L_ALT_OP_ADD_INT: /* 0x90 */ 12130/* File: x86/alt_stub.S */ 12131/* 12132 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12133 * any interesting requests and then jump to the real instruction 12134 * handler. Unlike the Arm handler, we can't do this as a tail call 12135 * because rIBASE is caller save and we need to reload it. 12136 * 12137 * Note that unlike in the Arm implementation, we should never arrive 12138 * here with a zero breakFlag because we always refresh rIBASE on 12139 * return. 12140 */ 12141 EXPORT_PC 12142 movl rSELF, %eax 12143 movl rPC, OUT_ARG0(%esp) 12144 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12145 movl rFP, OUT_ARG1(%esp) 12146 je 1f # reload rIBASE & resume if not 12147 movl %eax, OUT_ARG2(%esp) 12148 call dvmCheckBefore # (dPC, dFP, self) 12149 movl rSELF, %eax 121501: 12151 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12152 jmp *dvmAsmInstructionStart+(144*4) 12153 12154/* ------------------------------ */ 12155.L_ALT_OP_SUB_INT: /* 0x91 */ 12156/* File: x86/alt_stub.S */ 12157/* 12158 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12159 * any interesting requests and then jump to the real instruction 12160 * handler. Unlike the Arm handler, we can't do this as a tail call 12161 * because rIBASE is caller save and we need to reload it. 12162 * 12163 * Note that unlike in the Arm implementation, we should never arrive 12164 * here with a zero breakFlag because we always refresh rIBASE on 12165 * return. 12166 */ 12167 EXPORT_PC 12168 movl rSELF, %eax 12169 movl rPC, OUT_ARG0(%esp) 12170 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12171 movl rFP, OUT_ARG1(%esp) 12172 je 1f # reload rIBASE & resume if not 12173 movl %eax, OUT_ARG2(%esp) 12174 call dvmCheckBefore # (dPC, dFP, self) 12175 movl rSELF, %eax 121761: 12177 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12178 jmp *dvmAsmInstructionStart+(145*4) 12179 12180/* ------------------------------ */ 12181.L_ALT_OP_MUL_INT: /* 0x92 */ 12182/* File: x86/alt_stub.S */ 12183/* 12184 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12185 * any interesting requests and then jump to the real instruction 12186 * handler. Unlike the Arm handler, we can't do this as a tail call 12187 * because rIBASE is caller save and we need to reload it. 12188 * 12189 * Note that unlike in the Arm implementation, we should never arrive 12190 * here with a zero breakFlag because we always refresh rIBASE on 12191 * return. 12192 */ 12193 EXPORT_PC 12194 movl rSELF, %eax 12195 movl rPC, OUT_ARG0(%esp) 12196 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12197 movl rFP, OUT_ARG1(%esp) 12198 je 1f # reload rIBASE & resume if not 12199 movl %eax, OUT_ARG2(%esp) 12200 call dvmCheckBefore # (dPC, dFP, self) 12201 movl rSELF, %eax 122021: 12203 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12204 jmp *dvmAsmInstructionStart+(146*4) 12205 12206/* ------------------------------ */ 12207.L_ALT_OP_DIV_INT: /* 0x93 */ 12208/* File: x86/alt_stub.S */ 12209/* 12210 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12211 * any interesting requests and then jump to the real instruction 12212 * handler. Unlike the Arm handler, we can't do this as a tail call 12213 * because rIBASE is caller save and we need to reload it. 12214 * 12215 * Note that unlike in the Arm implementation, we should never arrive 12216 * here with a zero breakFlag because we always refresh rIBASE on 12217 * return. 12218 */ 12219 EXPORT_PC 12220 movl rSELF, %eax 12221 movl rPC, OUT_ARG0(%esp) 12222 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12223 movl rFP, OUT_ARG1(%esp) 12224 je 1f # reload rIBASE & resume if not 12225 movl %eax, OUT_ARG2(%esp) 12226 call dvmCheckBefore # (dPC, dFP, self) 12227 movl rSELF, %eax 122281: 12229 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12230 jmp *dvmAsmInstructionStart+(147*4) 12231 12232/* ------------------------------ */ 12233.L_ALT_OP_REM_INT: /* 0x94 */ 12234/* File: x86/alt_stub.S */ 12235/* 12236 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12237 * any interesting requests and then jump to the real instruction 12238 * handler. Unlike the Arm handler, we can't do this as a tail call 12239 * because rIBASE is caller save and we need to reload it. 12240 * 12241 * Note that unlike in the Arm implementation, we should never arrive 12242 * here with a zero breakFlag because we always refresh rIBASE on 12243 * return. 12244 */ 12245 EXPORT_PC 12246 movl rSELF, %eax 12247 movl rPC, OUT_ARG0(%esp) 12248 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12249 movl rFP, OUT_ARG1(%esp) 12250 je 1f # reload rIBASE & resume if not 12251 movl %eax, OUT_ARG2(%esp) 12252 call dvmCheckBefore # (dPC, dFP, self) 12253 movl rSELF, %eax 122541: 12255 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12256 jmp *dvmAsmInstructionStart+(148*4) 12257 12258/* ------------------------------ */ 12259.L_ALT_OP_AND_INT: /* 0x95 */ 12260/* File: x86/alt_stub.S */ 12261/* 12262 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12263 * any interesting requests and then jump to the real instruction 12264 * handler. Unlike the Arm handler, we can't do this as a tail call 12265 * because rIBASE is caller save and we need to reload it. 12266 * 12267 * Note that unlike in the Arm implementation, we should never arrive 12268 * here with a zero breakFlag because we always refresh rIBASE on 12269 * return. 12270 */ 12271 EXPORT_PC 12272 movl rSELF, %eax 12273 movl rPC, OUT_ARG0(%esp) 12274 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12275 movl rFP, OUT_ARG1(%esp) 12276 je 1f # reload rIBASE & resume if not 12277 movl %eax, OUT_ARG2(%esp) 12278 call dvmCheckBefore # (dPC, dFP, self) 12279 movl rSELF, %eax 122801: 12281 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12282 jmp *dvmAsmInstructionStart+(149*4) 12283 12284/* ------------------------------ */ 12285.L_ALT_OP_OR_INT: /* 0x96 */ 12286/* File: x86/alt_stub.S */ 12287/* 12288 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12289 * any interesting requests and then jump to the real instruction 12290 * handler. Unlike the Arm handler, we can't do this as a tail call 12291 * because rIBASE is caller save and we need to reload it. 12292 * 12293 * Note that unlike in the Arm implementation, we should never arrive 12294 * here with a zero breakFlag because we always refresh rIBASE on 12295 * return. 12296 */ 12297 EXPORT_PC 12298 movl rSELF, %eax 12299 movl rPC, OUT_ARG0(%esp) 12300 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12301 movl rFP, OUT_ARG1(%esp) 12302 je 1f # reload rIBASE & resume if not 12303 movl %eax, OUT_ARG2(%esp) 12304 call dvmCheckBefore # (dPC, dFP, self) 12305 movl rSELF, %eax 123061: 12307 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12308 jmp *dvmAsmInstructionStart+(150*4) 12309 12310/* ------------------------------ */ 12311.L_ALT_OP_XOR_INT: /* 0x97 */ 12312/* File: x86/alt_stub.S */ 12313/* 12314 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12315 * any interesting requests and then jump to the real instruction 12316 * handler. Unlike the Arm handler, we can't do this as a tail call 12317 * because rIBASE is caller save and we need to reload it. 12318 * 12319 * Note that unlike in the Arm implementation, we should never arrive 12320 * here with a zero breakFlag because we always refresh rIBASE on 12321 * return. 12322 */ 12323 EXPORT_PC 12324 movl rSELF, %eax 12325 movl rPC, OUT_ARG0(%esp) 12326 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12327 movl rFP, OUT_ARG1(%esp) 12328 je 1f # reload rIBASE & resume if not 12329 movl %eax, OUT_ARG2(%esp) 12330 call dvmCheckBefore # (dPC, dFP, self) 12331 movl rSELF, %eax 123321: 12333 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12334 jmp *dvmAsmInstructionStart+(151*4) 12335 12336/* ------------------------------ */ 12337.L_ALT_OP_SHL_INT: /* 0x98 */ 12338/* File: x86/alt_stub.S */ 12339/* 12340 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12341 * any interesting requests and then jump to the real instruction 12342 * handler. Unlike the Arm handler, we can't do this as a tail call 12343 * because rIBASE is caller save and we need to reload it. 12344 * 12345 * Note that unlike in the Arm implementation, we should never arrive 12346 * here with a zero breakFlag because we always refresh rIBASE on 12347 * return. 12348 */ 12349 EXPORT_PC 12350 movl rSELF, %eax 12351 movl rPC, OUT_ARG0(%esp) 12352 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12353 movl rFP, OUT_ARG1(%esp) 12354 je 1f # reload rIBASE & resume if not 12355 movl %eax, OUT_ARG2(%esp) 12356 call dvmCheckBefore # (dPC, dFP, self) 12357 movl rSELF, %eax 123581: 12359 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12360 jmp *dvmAsmInstructionStart+(152*4) 12361 12362/* ------------------------------ */ 12363.L_ALT_OP_SHR_INT: /* 0x99 */ 12364/* File: x86/alt_stub.S */ 12365/* 12366 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12367 * any interesting requests and then jump to the real instruction 12368 * handler. Unlike the Arm handler, we can't do this as a tail call 12369 * because rIBASE is caller save and we need to reload it. 12370 * 12371 * Note that unlike in the Arm implementation, we should never arrive 12372 * here with a zero breakFlag because we always refresh rIBASE on 12373 * return. 12374 */ 12375 EXPORT_PC 12376 movl rSELF, %eax 12377 movl rPC, OUT_ARG0(%esp) 12378 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12379 movl rFP, OUT_ARG1(%esp) 12380 je 1f # reload rIBASE & resume if not 12381 movl %eax, OUT_ARG2(%esp) 12382 call dvmCheckBefore # (dPC, dFP, self) 12383 movl rSELF, %eax 123841: 12385 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12386 jmp *dvmAsmInstructionStart+(153*4) 12387 12388/* ------------------------------ */ 12389.L_ALT_OP_USHR_INT: /* 0x9a */ 12390/* File: x86/alt_stub.S */ 12391/* 12392 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12393 * any interesting requests and then jump to the real instruction 12394 * handler. Unlike the Arm handler, we can't do this as a tail call 12395 * because rIBASE is caller save and we need to reload it. 12396 * 12397 * Note that unlike in the Arm implementation, we should never arrive 12398 * here with a zero breakFlag because we always refresh rIBASE on 12399 * return. 12400 */ 12401 EXPORT_PC 12402 movl rSELF, %eax 12403 movl rPC, OUT_ARG0(%esp) 12404 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12405 movl rFP, OUT_ARG1(%esp) 12406 je 1f # reload rIBASE & resume if not 12407 movl %eax, OUT_ARG2(%esp) 12408 call dvmCheckBefore # (dPC, dFP, self) 12409 movl rSELF, %eax 124101: 12411 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12412 jmp *dvmAsmInstructionStart+(154*4) 12413 12414/* ------------------------------ */ 12415.L_ALT_OP_ADD_LONG: /* 0x9b */ 12416/* File: x86/alt_stub.S */ 12417/* 12418 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12419 * any interesting requests and then jump to the real instruction 12420 * handler. Unlike the Arm handler, we can't do this as a tail call 12421 * because rIBASE is caller save and we need to reload it. 12422 * 12423 * Note that unlike in the Arm implementation, we should never arrive 12424 * here with a zero breakFlag because we always refresh rIBASE on 12425 * return. 12426 */ 12427 EXPORT_PC 12428 movl rSELF, %eax 12429 movl rPC, OUT_ARG0(%esp) 12430 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12431 movl rFP, OUT_ARG1(%esp) 12432 je 1f # reload rIBASE & resume if not 12433 movl %eax, OUT_ARG2(%esp) 12434 call dvmCheckBefore # (dPC, dFP, self) 12435 movl rSELF, %eax 124361: 12437 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12438 jmp *dvmAsmInstructionStart+(155*4) 12439 12440/* ------------------------------ */ 12441.L_ALT_OP_SUB_LONG: /* 0x9c */ 12442/* File: x86/alt_stub.S */ 12443/* 12444 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12445 * any interesting requests and then jump to the real instruction 12446 * handler. Unlike the Arm handler, we can't do this as a tail call 12447 * because rIBASE is caller save and we need to reload it. 12448 * 12449 * Note that unlike in the Arm implementation, we should never arrive 12450 * here with a zero breakFlag because we always refresh rIBASE on 12451 * return. 12452 */ 12453 EXPORT_PC 12454 movl rSELF, %eax 12455 movl rPC, OUT_ARG0(%esp) 12456 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12457 movl rFP, OUT_ARG1(%esp) 12458 je 1f # reload rIBASE & resume if not 12459 movl %eax, OUT_ARG2(%esp) 12460 call dvmCheckBefore # (dPC, dFP, self) 12461 movl rSELF, %eax 124621: 12463 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12464 jmp *dvmAsmInstructionStart+(156*4) 12465 12466/* ------------------------------ */ 12467.L_ALT_OP_MUL_LONG: /* 0x9d */ 12468/* File: x86/alt_stub.S */ 12469/* 12470 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12471 * any interesting requests and then jump to the real instruction 12472 * handler. Unlike the Arm handler, we can't do this as a tail call 12473 * because rIBASE is caller save and we need to reload it. 12474 * 12475 * Note that unlike in the Arm implementation, we should never arrive 12476 * here with a zero breakFlag because we always refresh rIBASE on 12477 * return. 12478 */ 12479 EXPORT_PC 12480 movl rSELF, %eax 12481 movl rPC, OUT_ARG0(%esp) 12482 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12483 movl rFP, OUT_ARG1(%esp) 12484 je 1f # reload rIBASE & resume if not 12485 movl %eax, OUT_ARG2(%esp) 12486 call dvmCheckBefore # (dPC, dFP, self) 12487 movl rSELF, %eax 124881: 12489 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12490 jmp *dvmAsmInstructionStart+(157*4) 12491 12492/* ------------------------------ */ 12493.L_ALT_OP_DIV_LONG: /* 0x9e */ 12494/* File: x86/alt_stub.S */ 12495/* 12496 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12497 * any interesting requests and then jump to the real instruction 12498 * handler. Unlike the Arm handler, we can't do this as a tail call 12499 * because rIBASE is caller save and we need to reload it. 12500 * 12501 * Note that unlike in the Arm implementation, we should never arrive 12502 * here with a zero breakFlag because we always refresh rIBASE on 12503 * return. 12504 */ 12505 EXPORT_PC 12506 movl rSELF, %eax 12507 movl rPC, OUT_ARG0(%esp) 12508 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12509 movl rFP, OUT_ARG1(%esp) 12510 je 1f # reload rIBASE & resume if not 12511 movl %eax, OUT_ARG2(%esp) 12512 call dvmCheckBefore # (dPC, dFP, self) 12513 movl rSELF, %eax 125141: 12515 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12516 jmp *dvmAsmInstructionStart+(158*4) 12517 12518/* ------------------------------ */ 12519.L_ALT_OP_REM_LONG: /* 0x9f */ 12520/* File: x86/alt_stub.S */ 12521/* 12522 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12523 * any interesting requests and then jump to the real instruction 12524 * handler. Unlike the Arm handler, we can't do this as a tail call 12525 * because rIBASE is caller save and we need to reload it. 12526 * 12527 * Note that unlike in the Arm implementation, we should never arrive 12528 * here with a zero breakFlag because we always refresh rIBASE on 12529 * return. 12530 */ 12531 EXPORT_PC 12532 movl rSELF, %eax 12533 movl rPC, OUT_ARG0(%esp) 12534 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12535 movl rFP, OUT_ARG1(%esp) 12536 je 1f # reload rIBASE & resume if not 12537 movl %eax, OUT_ARG2(%esp) 12538 call dvmCheckBefore # (dPC, dFP, self) 12539 movl rSELF, %eax 125401: 12541 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12542 jmp *dvmAsmInstructionStart+(159*4) 12543 12544/* ------------------------------ */ 12545.L_ALT_OP_AND_LONG: /* 0xa0 */ 12546/* File: x86/alt_stub.S */ 12547/* 12548 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12549 * any interesting requests and then jump to the real instruction 12550 * handler. Unlike the Arm handler, we can't do this as a tail call 12551 * because rIBASE is caller save and we need to reload it. 12552 * 12553 * Note that unlike in the Arm implementation, we should never arrive 12554 * here with a zero breakFlag because we always refresh rIBASE on 12555 * return. 12556 */ 12557 EXPORT_PC 12558 movl rSELF, %eax 12559 movl rPC, OUT_ARG0(%esp) 12560 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12561 movl rFP, OUT_ARG1(%esp) 12562 je 1f # reload rIBASE & resume if not 12563 movl %eax, OUT_ARG2(%esp) 12564 call dvmCheckBefore # (dPC, dFP, self) 12565 movl rSELF, %eax 125661: 12567 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12568 jmp *dvmAsmInstructionStart+(160*4) 12569 12570/* ------------------------------ */ 12571.L_ALT_OP_OR_LONG: /* 0xa1 */ 12572/* File: x86/alt_stub.S */ 12573/* 12574 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12575 * any interesting requests and then jump to the real instruction 12576 * handler. Unlike the Arm handler, we can't do this as a tail call 12577 * because rIBASE is caller save and we need to reload it. 12578 * 12579 * Note that unlike in the Arm implementation, we should never arrive 12580 * here with a zero breakFlag because we always refresh rIBASE on 12581 * return. 12582 */ 12583 EXPORT_PC 12584 movl rSELF, %eax 12585 movl rPC, OUT_ARG0(%esp) 12586 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12587 movl rFP, OUT_ARG1(%esp) 12588 je 1f # reload rIBASE & resume if not 12589 movl %eax, OUT_ARG2(%esp) 12590 call dvmCheckBefore # (dPC, dFP, self) 12591 movl rSELF, %eax 125921: 12593 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12594 jmp *dvmAsmInstructionStart+(161*4) 12595 12596/* ------------------------------ */ 12597.L_ALT_OP_XOR_LONG: /* 0xa2 */ 12598/* File: x86/alt_stub.S */ 12599/* 12600 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12601 * any interesting requests and then jump to the real instruction 12602 * handler. Unlike the Arm handler, we can't do this as a tail call 12603 * because rIBASE is caller save and we need to reload it. 12604 * 12605 * Note that unlike in the Arm implementation, we should never arrive 12606 * here with a zero breakFlag because we always refresh rIBASE on 12607 * return. 12608 */ 12609 EXPORT_PC 12610 movl rSELF, %eax 12611 movl rPC, OUT_ARG0(%esp) 12612 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12613 movl rFP, OUT_ARG1(%esp) 12614 je 1f # reload rIBASE & resume if not 12615 movl %eax, OUT_ARG2(%esp) 12616 call dvmCheckBefore # (dPC, dFP, self) 12617 movl rSELF, %eax 126181: 12619 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12620 jmp *dvmAsmInstructionStart+(162*4) 12621 12622/* ------------------------------ */ 12623.L_ALT_OP_SHL_LONG: /* 0xa3 */ 12624/* File: x86/alt_stub.S */ 12625/* 12626 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12627 * any interesting requests and then jump to the real instruction 12628 * handler. Unlike the Arm handler, we can't do this as a tail call 12629 * because rIBASE is caller save and we need to reload it. 12630 * 12631 * Note that unlike in the Arm implementation, we should never arrive 12632 * here with a zero breakFlag because we always refresh rIBASE on 12633 * return. 12634 */ 12635 EXPORT_PC 12636 movl rSELF, %eax 12637 movl rPC, OUT_ARG0(%esp) 12638 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12639 movl rFP, OUT_ARG1(%esp) 12640 je 1f # reload rIBASE & resume if not 12641 movl %eax, OUT_ARG2(%esp) 12642 call dvmCheckBefore # (dPC, dFP, self) 12643 movl rSELF, %eax 126441: 12645 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12646 jmp *dvmAsmInstructionStart+(163*4) 12647 12648/* ------------------------------ */ 12649.L_ALT_OP_SHR_LONG: /* 0xa4 */ 12650/* File: x86/alt_stub.S */ 12651/* 12652 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12653 * any interesting requests and then jump to the real instruction 12654 * handler. Unlike the Arm handler, we can't do this as a tail call 12655 * because rIBASE is caller save and we need to reload it. 12656 * 12657 * Note that unlike in the Arm implementation, we should never arrive 12658 * here with a zero breakFlag because we always refresh rIBASE on 12659 * return. 12660 */ 12661 EXPORT_PC 12662 movl rSELF, %eax 12663 movl rPC, OUT_ARG0(%esp) 12664 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12665 movl rFP, OUT_ARG1(%esp) 12666 je 1f # reload rIBASE & resume if not 12667 movl %eax, OUT_ARG2(%esp) 12668 call dvmCheckBefore # (dPC, dFP, self) 12669 movl rSELF, %eax 126701: 12671 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12672 jmp *dvmAsmInstructionStart+(164*4) 12673 12674/* ------------------------------ */ 12675.L_ALT_OP_USHR_LONG: /* 0xa5 */ 12676/* File: x86/alt_stub.S */ 12677/* 12678 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12679 * any interesting requests and then jump to the real instruction 12680 * handler. Unlike the Arm handler, we can't do this as a tail call 12681 * because rIBASE is caller save and we need to reload it. 12682 * 12683 * Note that unlike in the Arm implementation, we should never arrive 12684 * here with a zero breakFlag because we always refresh rIBASE on 12685 * return. 12686 */ 12687 EXPORT_PC 12688 movl rSELF, %eax 12689 movl rPC, OUT_ARG0(%esp) 12690 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12691 movl rFP, OUT_ARG1(%esp) 12692 je 1f # reload rIBASE & resume if not 12693 movl %eax, OUT_ARG2(%esp) 12694 call dvmCheckBefore # (dPC, dFP, self) 12695 movl rSELF, %eax 126961: 12697 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12698 jmp *dvmAsmInstructionStart+(165*4) 12699 12700/* ------------------------------ */ 12701.L_ALT_OP_ADD_FLOAT: /* 0xa6 */ 12702/* File: x86/alt_stub.S */ 12703/* 12704 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12705 * any interesting requests and then jump to the real instruction 12706 * handler. Unlike the Arm handler, we can't do this as a tail call 12707 * because rIBASE is caller save and we need to reload it. 12708 * 12709 * Note that unlike in the Arm implementation, we should never arrive 12710 * here with a zero breakFlag because we always refresh rIBASE on 12711 * return. 12712 */ 12713 EXPORT_PC 12714 movl rSELF, %eax 12715 movl rPC, OUT_ARG0(%esp) 12716 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12717 movl rFP, OUT_ARG1(%esp) 12718 je 1f # reload rIBASE & resume if not 12719 movl %eax, OUT_ARG2(%esp) 12720 call dvmCheckBefore # (dPC, dFP, self) 12721 movl rSELF, %eax 127221: 12723 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12724 jmp *dvmAsmInstructionStart+(166*4) 12725 12726/* ------------------------------ */ 12727.L_ALT_OP_SUB_FLOAT: /* 0xa7 */ 12728/* File: x86/alt_stub.S */ 12729/* 12730 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12731 * any interesting requests and then jump to the real instruction 12732 * handler. Unlike the Arm handler, we can't do this as a tail call 12733 * because rIBASE is caller save and we need to reload it. 12734 * 12735 * Note that unlike in the Arm implementation, we should never arrive 12736 * here with a zero breakFlag because we always refresh rIBASE on 12737 * return. 12738 */ 12739 EXPORT_PC 12740 movl rSELF, %eax 12741 movl rPC, OUT_ARG0(%esp) 12742 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12743 movl rFP, OUT_ARG1(%esp) 12744 je 1f # reload rIBASE & resume if not 12745 movl %eax, OUT_ARG2(%esp) 12746 call dvmCheckBefore # (dPC, dFP, self) 12747 movl rSELF, %eax 127481: 12749 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12750 jmp *dvmAsmInstructionStart+(167*4) 12751 12752/* ------------------------------ */ 12753.L_ALT_OP_MUL_FLOAT: /* 0xa8 */ 12754/* File: x86/alt_stub.S */ 12755/* 12756 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12757 * any interesting requests and then jump to the real instruction 12758 * handler. Unlike the Arm handler, we can't do this as a tail call 12759 * because rIBASE is caller save and we need to reload it. 12760 * 12761 * Note that unlike in the Arm implementation, we should never arrive 12762 * here with a zero breakFlag because we always refresh rIBASE on 12763 * return. 12764 */ 12765 EXPORT_PC 12766 movl rSELF, %eax 12767 movl rPC, OUT_ARG0(%esp) 12768 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12769 movl rFP, OUT_ARG1(%esp) 12770 je 1f # reload rIBASE & resume if not 12771 movl %eax, OUT_ARG2(%esp) 12772 call dvmCheckBefore # (dPC, dFP, self) 12773 movl rSELF, %eax 127741: 12775 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12776 jmp *dvmAsmInstructionStart+(168*4) 12777 12778/* ------------------------------ */ 12779.L_ALT_OP_DIV_FLOAT: /* 0xa9 */ 12780/* File: x86/alt_stub.S */ 12781/* 12782 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12783 * any interesting requests and then jump to the real instruction 12784 * handler. Unlike the Arm handler, we can't do this as a tail call 12785 * because rIBASE is caller save and we need to reload it. 12786 * 12787 * Note that unlike in the Arm implementation, we should never arrive 12788 * here with a zero breakFlag because we always refresh rIBASE on 12789 * return. 12790 */ 12791 EXPORT_PC 12792 movl rSELF, %eax 12793 movl rPC, OUT_ARG0(%esp) 12794 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12795 movl rFP, OUT_ARG1(%esp) 12796 je 1f # reload rIBASE & resume if not 12797 movl %eax, OUT_ARG2(%esp) 12798 call dvmCheckBefore # (dPC, dFP, self) 12799 movl rSELF, %eax 128001: 12801 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12802 jmp *dvmAsmInstructionStart+(169*4) 12803 12804/* ------------------------------ */ 12805.L_ALT_OP_REM_FLOAT: /* 0xaa */ 12806/* File: x86/alt_stub.S */ 12807/* 12808 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12809 * any interesting requests and then jump to the real instruction 12810 * handler. Unlike the Arm handler, we can't do this as a tail call 12811 * because rIBASE is caller save and we need to reload it. 12812 * 12813 * Note that unlike in the Arm implementation, we should never arrive 12814 * here with a zero breakFlag because we always refresh rIBASE on 12815 * return. 12816 */ 12817 EXPORT_PC 12818 movl rSELF, %eax 12819 movl rPC, OUT_ARG0(%esp) 12820 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12821 movl rFP, OUT_ARG1(%esp) 12822 je 1f # reload rIBASE & resume if not 12823 movl %eax, OUT_ARG2(%esp) 12824 call dvmCheckBefore # (dPC, dFP, self) 12825 movl rSELF, %eax 128261: 12827 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12828 jmp *dvmAsmInstructionStart+(170*4) 12829 12830/* ------------------------------ */ 12831.L_ALT_OP_ADD_DOUBLE: /* 0xab */ 12832/* File: x86/alt_stub.S */ 12833/* 12834 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12835 * any interesting requests and then jump to the real instruction 12836 * handler. Unlike the Arm handler, we can't do this as a tail call 12837 * because rIBASE is caller save and we need to reload it. 12838 * 12839 * Note that unlike in the Arm implementation, we should never arrive 12840 * here with a zero breakFlag because we always refresh rIBASE on 12841 * return. 12842 */ 12843 EXPORT_PC 12844 movl rSELF, %eax 12845 movl rPC, OUT_ARG0(%esp) 12846 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12847 movl rFP, OUT_ARG1(%esp) 12848 je 1f # reload rIBASE & resume if not 12849 movl %eax, OUT_ARG2(%esp) 12850 call dvmCheckBefore # (dPC, dFP, self) 12851 movl rSELF, %eax 128521: 12853 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12854 jmp *dvmAsmInstructionStart+(171*4) 12855 12856/* ------------------------------ */ 12857.L_ALT_OP_SUB_DOUBLE: /* 0xac */ 12858/* File: x86/alt_stub.S */ 12859/* 12860 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12861 * any interesting requests and then jump to the real instruction 12862 * handler. Unlike the Arm handler, we can't do this as a tail call 12863 * because rIBASE is caller save and we need to reload it. 12864 * 12865 * Note that unlike in the Arm implementation, we should never arrive 12866 * here with a zero breakFlag because we always refresh rIBASE on 12867 * return. 12868 */ 12869 EXPORT_PC 12870 movl rSELF, %eax 12871 movl rPC, OUT_ARG0(%esp) 12872 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12873 movl rFP, OUT_ARG1(%esp) 12874 je 1f # reload rIBASE & resume if not 12875 movl %eax, OUT_ARG2(%esp) 12876 call dvmCheckBefore # (dPC, dFP, self) 12877 movl rSELF, %eax 128781: 12879 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12880 jmp *dvmAsmInstructionStart+(172*4) 12881 12882/* ------------------------------ */ 12883.L_ALT_OP_MUL_DOUBLE: /* 0xad */ 12884/* File: x86/alt_stub.S */ 12885/* 12886 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12887 * any interesting requests and then jump to the real instruction 12888 * handler. Unlike the Arm handler, we can't do this as a tail call 12889 * because rIBASE is caller save and we need to reload it. 12890 * 12891 * Note that unlike in the Arm implementation, we should never arrive 12892 * here with a zero breakFlag because we always refresh rIBASE on 12893 * return. 12894 */ 12895 EXPORT_PC 12896 movl rSELF, %eax 12897 movl rPC, OUT_ARG0(%esp) 12898 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12899 movl rFP, OUT_ARG1(%esp) 12900 je 1f # reload rIBASE & resume if not 12901 movl %eax, OUT_ARG2(%esp) 12902 call dvmCheckBefore # (dPC, dFP, self) 12903 movl rSELF, %eax 129041: 12905 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12906 jmp *dvmAsmInstructionStart+(173*4) 12907 12908/* ------------------------------ */ 12909.L_ALT_OP_DIV_DOUBLE: /* 0xae */ 12910/* File: x86/alt_stub.S */ 12911/* 12912 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12913 * any interesting requests and then jump to the real instruction 12914 * handler. Unlike the Arm handler, we can't do this as a tail call 12915 * because rIBASE is caller save and we need to reload it. 12916 * 12917 * Note that unlike in the Arm implementation, we should never arrive 12918 * here with a zero breakFlag because we always refresh rIBASE on 12919 * return. 12920 */ 12921 EXPORT_PC 12922 movl rSELF, %eax 12923 movl rPC, OUT_ARG0(%esp) 12924 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12925 movl rFP, OUT_ARG1(%esp) 12926 je 1f # reload rIBASE & resume if not 12927 movl %eax, OUT_ARG2(%esp) 12928 call dvmCheckBefore # (dPC, dFP, self) 12929 movl rSELF, %eax 129301: 12931 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12932 jmp *dvmAsmInstructionStart+(174*4) 12933 12934/* ------------------------------ */ 12935.L_ALT_OP_REM_DOUBLE: /* 0xaf */ 12936/* File: x86/alt_stub.S */ 12937/* 12938 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12939 * any interesting requests and then jump to the real instruction 12940 * handler. Unlike the Arm handler, we can't do this as a tail call 12941 * because rIBASE is caller save and we need to reload it. 12942 * 12943 * Note that unlike in the Arm implementation, we should never arrive 12944 * here with a zero breakFlag because we always refresh rIBASE on 12945 * return. 12946 */ 12947 EXPORT_PC 12948 movl rSELF, %eax 12949 movl rPC, OUT_ARG0(%esp) 12950 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12951 movl rFP, OUT_ARG1(%esp) 12952 je 1f # reload rIBASE & resume if not 12953 movl %eax, OUT_ARG2(%esp) 12954 call dvmCheckBefore # (dPC, dFP, self) 12955 movl rSELF, %eax 129561: 12957 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12958 jmp *dvmAsmInstructionStart+(175*4) 12959 12960/* ------------------------------ */ 12961.L_ALT_OP_ADD_INT_2ADDR: /* 0xb0 */ 12962/* File: x86/alt_stub.S */ 12963/* 12964 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12965 * any interesting requests and then jump to the real instruction 12966 * handler. Unlike the Arm handler, we can't do this as a tail call 12967 * because rIBASE is caller save and we need to reload it. 12968 * 12969 * Note that unlike in the Arm implementation, we should never arrive 12970 * here with a zero breakFlag because we always refresh rIBASE on 12971 * return. 12972 */ 12973 EXPORT_PC 12974 movl rSELF, %eax 12975 movl rPC, OUT_ARG0(%esp) 12976 cmpb $0,offThread_breakFlags(%eax) # anything to do? 12977 movl rFP, OUT_ARG1(%esp) 12978 je 1f # reload rIBASE & resume if not 12979 movl %eax, OUT_ARG2(%esp) 12980 call dvmCheckBefore # (dPC, dFP, self) 12981 movl rSELF, %eax 129821: 12983 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 12984 jmp *dvmAsmInstructionStart+(176*4) 12985 12986/* ------------------------------ */ 12987.L_ALT_OP_SUB_INT_2ADDR: /* 0xb1 */ 12988/* File: x86/alt_stub.S */ 12989/* 12990 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12991 * any interesting requests and then jump to the real instruction 12992 * handler. Unlike the Arm handler, we can't do this as a tail call 12993 * because rIBASE is caller save and we need to reload it. 12994 * 12995 * Note that unlike in the Arm implementation, we should never arrive 12996 * here with a zero breakFlag because we always refresh rIBASE on 12997 * return. 12998 */ 12999 EXPORT_PC 13000 movl rSELF, %eax 13001 movl rPC, OUT_ARG0(%esp) 13002 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13003 movl rFP, OUT_ARG1(%esp) 13004 je 1f # reload rIBASE & resume if not 13005 movl %eax, OUT_ARG2(%esp) 13006 call dvmCheckBefore # (dPC, dFP, self) 13007 movl rSELF, %eax 130081: 13009 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13010 jmp *dvmAsmInstructionStart+(177*4) 13011 13012/* ------------------------------ */ 13013.L_ALT_OP_MUL_INT_2ADDR: /* 0xb2 */ 13014/* File: x86/alt_stub.S */ 13015/* 13016 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13017 * any interesting requests and then jump to the real instruction 13018 * handler. Unlike the Arm handler, we can't do this as a tail call 13019 * because rIBASE is caller save and we need to reload it. 13020 * 13021 * Note that unlike in the Arm implementation, we should never arrive 13022 * here with a zero breakFlag because we always refresh rIBASE on 13023 * return. 13024 */ 13025 EXPORT_PC 13026 movl rSELF, %eax 13027 movl rPC, OUT_ARG0(%esp) 13028 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13029 movl rFP, OUT_ARG1(%esp) 13030 je 1f # reload rIBASE & resume if not 13031 movl %eax, OUT_ARG2(%esp) 13032 call dvmCheckBefore # (dPC, dFP, self) 13033 movl rSELF, %eax 130341: 13035 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13036 jmp *dvmAsmInstructionStart+(178*4) 13037 13038/* ------------------------------ */ 13039.L_ALT_OP_DIV_INT_2ADDR: /* 0xb3 */ 13040/* File: x86/alt_stub.S */ 13041/* 13042 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13043 * any interesting requests and then jump to the real instruction 13044 * handler. Unlike the Arm handler, we can't do this as a tail call 13045 * because rIBASE is caller save and we need to reload it. 13046 * 13047 * Note that unlike in the Arm implementation, we should never arrive 13048 * here with a zero breakFlag because we always refresh rIBASE on 13049 * return. 13050 */ 13051 EXPORT_PC 13052 movl rSELF, %eax 13053 movl rPC, OUT_ARG0(%esp) 13054 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13055 movl rFP, OUT_ARG1(%esp) 13056 je 1f # reload rIBASE & resume if not 13057 movl %eax, OUT_ARG2(%esp) 13058 call dvmCheckBefore # (dPC, dFP, self) 13059 movl rSELF, %eax 130601: 13061 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13062 jmp *dvmAsmInstructionStart+(179*4) 13063 13064/* ------------------------------ */ 13065.L_ALT_OP_REM_INT_2ADDR: /* 0xb4 */ 13066/* File: x86/alt_stub.S */ 13067/* 13068 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13069 * any interesting requests and then jump to the real instruction 13070 * handler. Unlike the Arm handler, we can't do this as a tail call 13071 * because rIBASE is caller save and we need to reload it. 13072 * 13073 * Note that unlike in the Arm implementation, we should never arrive 13074 * here with a zero breakFlag because we always refresh rIBASE on 13075 * return. 13076 */ 13077 EXPORT_PC 13078 movl rSELF, %eax 13079 movl rPC, OUT_ARG0(%esp) 13080 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13081 movl rFP, OUT_ARG1(%esp) 13082 je 1f # reload rIBASE & resume if not 13083 movl %eax, OUT_ARG2(%esp) 13084 call dvmCheckBefore # (dPC, dFP, self) 13085 movl rSELF, %eax 130861: 13087 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13088 jmp *dvmAsmInstructionStart+(180*4) 13089 13090/* ------------------------------ */ 13091.L_ALT_OP_AND_INT_2ADDR: /* 0xb5 */ 13092/* File: x86/alt_stub.S */ 13093/* 13094 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13095 * any interesting requests and then jump to the real instruction 13096 * handler. Unlike the Arm handler, we can't do this as a tail call 13097 * because rIBASE is caller save and we need to reload it. 13098 * 13099 * Note that unlike in the Arm implementation, we should never arrive 13100 * here with a zero breakFlag because we always refresh rIBASE on 13101 * return. 13102 */ 13103 EXPORT_PC 13104 movl rSELF, %eax 13105 movl rPC, OUT_ARG0(%esp) 13106 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13107 movl rFP, OUT_ARG1(%esp) 13108 je 1f # reload rIBASE & resume if not 13109 movl %eax, OUT_ARG2(%esp) 13110 call dvmCheckBefore # (dPC, dFP, self) 13111 movl rSELF, %eax 131121: 13113 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13114 jmp *dvmAsmInstructionStart+(181*4) 13115 13116/* ------------------------------ */ 13117.L_ALT_OP_OR_INT_2ADDR: /* 0xb6 */ 13118/* File: x86/alt_stub.S */ 13119/* 13120 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13121 * any interesting requests and then jump to the real instruction 13122 * handler. Unlike the Arm handler, we can't do this as a tail call 13123 * because rIBASE is caller save and we need to reload it. 13124 * 13125 * Note that unlike in the Arm implementation, we should never arrive 13126 * here with a zero breakFlag because we always refresh rIBASE on 13127 * return. 13128 */ 13129 EXPORT_PC 13130 movl rSELF, %eax 13131 movl rPC, OUT_ARG0(%esp) 13132 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13133 movl rFP, OUT_ARG1(%esp) 13134 je 1f # reload rIBASE & resume if not 13135 movl %eax, OUT_ARG2(%esp) 13136 call dvmCheckBefore # (dPC, dFP, self) 13137 movl rSELF, %eax 131381: 13139 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13140 jmp *dvmAsmInstructionStart+(182*4) 13141 13142/* ------------------------------ */ 13143.L_ALT_OP_XOR_INT_2ADDR: /* 0xb7 */ 13144/* File: x86/alt_stub.S */ 13145/* 13146 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13147 * any interesting requests and then jump to the real instruction 13148 * handler. Unlike the Arm handler, we can't do this as a tail call 13149 * because rIBASE is caller save and we need to reload it. 13150 * 13151 * Note that unlike in the Arm implementation, we should never arrive 13152 * here with a zero breakFlag because we always refresh rIBASE on 13153 * return. 13154 */ 13155 EXPORT_PC 13156 movl rSELF, %eax 13157 movl rPC, OUT_ARG0(%esp) 13158 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13159 movl rFP, OUT_ARG1(%esp) 13160 je 1f # reload rIBASE & resume if not 13161 movl %eax, OUT_ARG2(%esp) 13162 call dvmCheckBefore # (dPC, dFP, self) 13163 movl rSELF, %eax 131641: 13165 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13166 jmp *dvmAsmInstructionStart+(183*4) 13167 13168/* ------------------------------ */ 13169.L_ALT_OP_SHL_INT_2ADDR: /* 0xb8 */ 13170/* File: x86/alt_stub.S */ 13171/* 13172 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13173 * any interesting requests and then jump to the real instruction 13174 * handler. Unlike the Arm handler, we can't do this as a tail call 13175 * because rIBASE is caller save and we need to reload it. 13176 * 13177 * Note that unlike in the Arm implementation, we should never arrive 13178 * here with a zero breakFlag because we always refresh rIBASE on 13179 * return. 13180 */ 13181 EXPORT_PC 13182 movl rSELF, %eax 13183 movl rPC, OUT_ARG0(%esp) 13184 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13185 movl rFP, OUT_ARG1(%esp) 13186 je 1f # reload rIBASE & resume if not 13187 movl %eax, OUT_ARG2(%esp) 13188 call dvmCheckBefore # (dPC, dFP, self) 13189 movl rSELF, %eax 131901: 13191 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13192 jmp *dvmAsmInstructionStart+(184*4) 13193 13194/* ------------------------------ */ 13195.L_ALT_OP_SHR_INT_2ADDR: /* 0xb9 */ 13196/* File: x86/alt_stub.S */ 13197/* 13198 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13199 * any interesting requests and then jump to the real instruction 13200 * handler. Unlike the Arm handler, we can't do this as a tail call 13201 * because rIBASE is caller save and we need to reload it. 13202 * 13203 * Note that unlike in the Arm implementation, we should never arrive 13204 * here with a zero breakFlag because we always refresh rIBASE on 13205 * return. 13206 */ 13207 EXPORT_PC 13208 movl rSELF, %eax 13209 movl rPC, OUT_ARG0(%esp) 13210 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13211 movl rFP, OUT_ARG1(%esp) 13212 je 1f # reload rIBASE & resume if not 13213 movl %eax, OUT_ARG2(%esp) 13214 call dvmCheckBefore # (dPC, dFP, self) 13215 movl rSELF, %eax 132161: 13217 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13218 jmp *dvmAsmInstructionStart+(185*4) 13219 13220/* ------------------------------ */ 13221.L_ALT_OP_USHR_INT_2ADDR: /* 0xba */ 13222/* File: x86/alt_stub.S */ 13223/* 13224 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13225 * any interesting requests and then jump to the real instruction 13226 * handler. Unlike the Arm handler, we can't do this as a tail call 13227 * because rIBASE is caller save and we need to reload it. 13228 * 13229 * Note that unlike in the Arm implementation, we should never arrive 13230 * here with a zero breakFlag because we always refresh rIBASE on 13231 * return. 13232 */ 13233 EXPORT_PC 13234 movl rSELF, %eax 13235 movl rPC, OUT_ARG0(%esp) 13236 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13237 movl rFP, OUT_ARG1(%esp) 13238 je 1f # reload rIBASE & resume if not 13239 movl %eax, OUT_ARG2(%esp) 13240 call dvmCheckBefore # (dPC, dFP, self) 13241 movl rSELF, %eax 132421: 13243 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13244 jmp *dvmAsmInstructionStart+(186*4) 13245 13246/* ------------------------------ */ 13247.L_ALT_OP_ADD_LONG_2ADDR: /* 0xbb */ 13248/* File: x86/alt_stub.S */ 13249/* 13250 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13251 * any interesting requests and then jump to the real instruction 13252 * handler. Unlike the Arm handler, we can't do this as a tail call 13253 * because rIBASE is caller save and we need to reload it. 13254 * 13255 * Note that unlike in the Arm implementation, we should never arrive 13256 * here with a zero breakFlag because we always refresh rIBASE on 13257 * return. 13258 */ 13259 EXPORT_PC 13260 movl rSELF, %eax 13261 movl rPC, OUT_ARG0(%esp) 13262 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13263 movl rFP, OUT_ARG1(%esp) 13264 je 1f # reload rIBASE & resume if not 13265 movl %eax, OUT_ARG2(%esp) 13266 call dvmCheckBefore # (dPC, dFP, self) 13267 movl rSELF, %eax 132681: 13269 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13270 jmp *dvmAsmInstructionStart+(187*4) 13271 13272/* ------------------------------ */ 13273.L_ALT_OP_SUB_LONG_2ADDR: /* 0xbc */ 13274/* File: x86/alt_stub.S */ 13275/* 13276 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13277 * any interesting requests and then jump to the real instruction 13278 * handler. Unlike the Arm handler, we can't do this as a tail call 13279 * because rIBASE is caller save and we need to reload it. 13280 * 13281 * Note that unlike in the Arm implementation, we should never arrive 13282 * here with a zero breakFlag because we always refresh rIBASE on 13283 * return. 13284 */ 13285 EXPORT_PC 13286 movl rSELF, %eax 13287 movl rPC, OUT_ARG0(%esp) 13288 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13289 movl rFP, OUT_ARG1(%esp) 13290 je 1f # reload rIBASE & resume if not 13291 movl %eax, OUT_ARG2(%esp) 13292 call dvmCheckBefore # (dPC, dFP, self) 13293 movl rSELF, %eax 132941: 13295 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13296 jmp *dvmAsmInstructionStart+(188*4) 13297 13298/* ------------------------------ */ 13299.L_ALT_OP_MUL_LONG_2ADDR: /* 0xbd */ 13300/* File: x86/alt_stub.S */ 13301/* 13302 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13303 * any interesting requests and then jump to the real instruction 13304 * handler. Unlike the Arm handler, we can't do this as a tail call 13305 * because rIBASE is caller save and we need to reload it. 13306 * 13307 * Note that unlike in the Arm implementation, we should never arrive 13308 * here with a zero breakFlag because we always refresh rIBASE on 13309 * return. 13310 */ 13311 EXPORT_PC 13312 movl rSELF, %eax 13313 movl rPC, OUT_ARG0(%esp) 13314 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13315 movl rFP, OUT_ARG1(%esp) 13316 je 1f # reload rIBASE & resume if not 13317 movl %eax, OUT_ARG2(%esp) 13318 call dvmCheckBefore # (dPC, dFP, self) 13319 movl rSELF, %eax 133201: 13321 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13322 jmp *dvmAsmInstructionStart+(189*4) 13323 13324/* ------------------------------ */ 13325.L_ALT_OP_DIV_LONG_2ADDR: /* 0xbe */ 13326/* File: x86/alt_stub.S */ 13327/* 13328 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13329 * any interesting requests and then jump to the real instruction 13330 * handler. Unlike the Arm handler, we can't do this as a tail call 13331 * because rIBASE is caller save and we need to reload it. 13332 * 13333 * Note that unlike in the Arm implementation, we should never arrive 13334 * here with a zero breakFlag because we always refresh rIBASE on 13335 * return. 13336 */ 13337 EXPORT_PC 13338 movl rSELF, %eax 13339 movl rPC, OUT_ARG0(%esp) 13340 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13341 movl rFP, OUT_ARG1(%esp) 13342 je 1f # reload rIBASE & resume if not 13343 movl %eax, OUT_ARG2(%esp) 13344 call dvmCheckBefore # (dPC, dFP, self) 13345 movl rSELF, %eax 133461: 13347 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13348 jmp *dvmAsmInstructionStart+(190*4) 13349 13350/* ------------------------------ */ 13351.L_ALT_OP_REM_LONG_2ADDR: /* 0xbf */ 13352/* File: x86/alt_stub.S */ 13353/* 13354 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13355 * any interesting requests and then jump to the real instruction 13356 * handler. Unlike the Arm handler, we can't do this as a tail call 13357 * because rIBASE is caller save and we need to reload it. 13358 * 13359 * Note that unlike in the Arm implementation, we should never arrive 13360 * here with a zero breakFlag because we always refresh rIBASE on 13361 * return. 13362 */ 13363 EXPORT_PC 13364 movl rSELF, %eax 13365 movl rPC, OUT_ARG0(%esp) 13366 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13367 movl rFP, OUT_ARG1(%esp) 13368 je 1f # reload rIBASE & resume if not 13369 movl %eax, OUT_ARG2(%esp) 13370 call dvmCheckBefore # (dPC, dFP, self) 13371 movl rSELF, %eax 133721: 13373 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13374 jmp *dvmAsmInstructionStart+(191*4) 13375 13376/* ------------------------------ */ 13377.L_ALT_OP_AND_LONG_2ADDR: /* 0xc0 */ 13378/* File: x86/alt_stub.S */ 13379/* 13380 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13381 * any interesting requests and then jump to the real instruction 13382 * handler. Unlike the Arm handler, we can't do this as a tail call 13383 * because rIBASE is caller save and we need to reload it. 13384 * 13385 * Note that unlike in the Arm implementation, we should never arrive 13386 * here with a zero breakFlag because we always refresh rIBASE on 13387 * return. 13388 */ 13389 EXPORT_PC 13390 movl rSELF, %eax 13391 movl rPC, OUT_ARG0(%esp) 13392 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13393 movl rFP, OUT_ARG1(%esp) 13394 je 1f # reload rIBASE & resume if not 13395 movl %eax, OUT_ARG2(%esp) 13396 call dvmCheckBefore # (dPC, dFP, self) 13397 movl rSELF, %eax 133981: 13399 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13400 jmp *dvmAsmInstructionStart+(192*4) 13401 13402/* ------------------------------ */ 13403.L_ALT_OP_OR_LONG_2ADDR: /* 0xc1 */ 13404/* File: x86/alt_stub.S */ 13405/* 13406 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13407 * any interesting requests and then jump to the real instruction 13408 * handler. Unlike the Arm handler, we can't do this as a tail call 13409 * because rIBASE is caller save and we need to reload it. 13410 * 13411 * Note that unlike in the Arm implementation, we should never arrive 13412 * here with a zero breakFlag because we always refresh rIBASE on 13413 * return. 13414 */ 13415 EXPORT_PC 13416 movl rSELF, %eax 13417 movl rPC, OUT_ARG0(%esp) 13418 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13419 movl rFP, OUT_ARG1(%esp) 13420 je 1f # reload rIBASE & resume if not 13421 movl %eax, OUT_ARG2(%esp) 13422 call dvmCheckBefore # (dPC, dFP, self) 13423 movl rSELF, %eax 134241: 13425 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13426 jmp *dvmAsmInstructionStart+(193*4) 13427 13428/* ------------------------------ */ 13429.L_ALT_OP_XOR_LONG_2ADDR: /* 0xc2 */ 13430/* File: x86/alt_stub.S */ 13431/* 13432 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13433 * any interesting requests and then jump to the real instruction 13434 * handler. Unlike the Arm handler, we can't do this as a tail call 13435 * because rIBASE is caller save and we need to reload it. 13436 * 13437 * Note that unlike in the Arm implementation, we should never arrive 13438 * here with a zero breakFlag because we always refresh rIBASE on 13439 * return. 13440 */ 13441 EXPORT_PC 13442 movl rSELF, %eax 13443 movl rPC, OUT_ARG0(%esp) 13444 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13445 movl rFP, OUT_ARG1(%esp) 13446 je 1f # reload rIBASE & resume if not 13447 movl %eax, OUT_ARG2(%esp) 13448 call dvmCheckBefore # (dPC, dFP, self) 13449 movl rSELF, %eax 134501: 13451 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13452 jmp *dvmAsmInstructionStart+(194*4) 13453 13454/* ------------------------------ */ 13455.L_ALT_OP_SHL_LONG_2ADDR: /* 0xc3 */ 13456/* File: x86/alt_stub.S */ 13457/* 13458 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13459 * any interesting requests and then jump to the real instruction 13460 * handler. Unlike the Arm handler, we can't do this as a tail call 13461 * because rIBASE is caller save and we need to reload it. 13462 * 13463 * Note that unlike in the Arm implementation, we should never arrive 13464 * here with a zero breakFlag because we always refresh rIBASE on 13465 * return. 13466 */ 13467 EXPORT_PC 13468 movl rSELF, %eax 13469 movl rPC, OUT_ARG0(%esp) 13470 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13471 movl rFP, OUT_ARG1(%esp) 13472 je 1f # reload rIBASE & resume if not 13473 movl %eax, OUT_ARG2(%esp) 13474 call dvmCheckBefore # (dPC, dFP, self) 13475 movl rSELF, %eax 134761: 13477 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13478 jmp *dvmAsmInstructionStart+(195*4) 13479 13480/* ------------------------------ */ 13481.L_ALT_OP_SHR_LONG_2ADDR: /* 0xc4 */ 13482/* File: x86/alt_stub.S */ 13483/* 13484 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13485 * any interesting requests and then jump to the real instruction 13486 * handler. Unlike the Arm handler, we can't do this as a tail call 13487 * because rIBASE is caller save and we need to reload it. 13488 * 13489 * Note that unlike in the Arm implementation, we should never arrive 13490 * here with a zero breakFlag because we always refresh rIBASE on 13491 * return. 13492 */ 13493 EXPORT_PC 13494 movl rSELF, %eax 13495 movl rPC, OUT_ARG0(%esp) 13496 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13497 movl rFP, OUT_ARG1(%esp) 13498 je 1f # reload rIBASE & resume if not 13499 movl %eax, OUT_ARG2(%esp) 13500 call dvmCheckBefore # (dPC, dFP, self) 13501 movl rSELF, %eax 135021: 13503 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13504 jmp *dvmAsmInstructionStart+(196*4) 13505 13506/* ------------------------------ */ 13507.L_ALT_OP_USHR_LONG_2ADDR: /* 0xc5 */ 13508/* File: x86/alt_stub.S */ 13509/* 13510 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13511 * any interesting requests and then jump to the real instruction 13512 * handler. Unlike the Arm handler, we can't do this as a tail call 13513 * because rIBASE is caller save and we need to reload it. 13514 * 13515 * Note that unlike in the Arm implementation, we should never arrive 13516 * here with a zero breakFlag because we always refresh rIBASE on 13517 * return. 13518 */ 13519 EXPORT_PC 13520 movl rSELF, %eax 13521 movl rPC, OUT_ARG0(%esp) 13522 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13523 movl rFP, OUT_ARG1(%esp) 13524 je 1f # reload rIBASE & resume if not 13525 movl %eax, OUT_ARG2(%esp) 13526 call dvmCheckBefore # (dPC, dFP, self) 13527 movl rSELF, %eax 135281: 13529 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13530 jmp *dvmAsmInstructionStart+(197*4) 13531 13532/* ------------------------------ */ 13533.L_ALT_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 13534/* File: x86/alt_stub.S */ 13535/* 13536 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13537 * any interesting requests and then jump to the real instruction 13538 * handler. Unlike the Arm handler, we can't do this as a tail call 13539 * because rIBASE is caller save and we need to reload it. 13540 * 13541 * Note that unlike in the Arm implementation, we should never arrive 13542 * here with a zero breakFlag because we always refresh rIBASE on 13543 * return. 13544 */ 13545 EXPORT_PC 13546 movl rSELF, %eax 13547 movl rPC, OUT_ARG0(%esp) 13548 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13549 movl rFP, OUT_ARG1(%esp) 13550 je 1f # reload rIBASE & resume if not 13551 movl %eax, OUT_ARG2(%esp) 13552 call dvmCheckBefore # (dPC, dFP, self) 13553 movl rSELF, %eax 135541: 13555 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13556 jmp *dvmAsmInstructionStart+(198*4) 13557 13558/* ------------------------------ */ 13559.L_ALT_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 13560/* File: x86/alt_stub.S */ 13561/* 13562 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13563 * any interesting requests and then jump to the real instruction 13564 * handler. Unlike the Arm handler, we can't do this as a tail call 13565 * because rIBASE is caller save and we need to reload it. 13566 * 13567 * Note that unlike in the Arm implementation, we should never arrive 13568 * here with a zero breakFlag because we always refresh rIBASE on 13569 * return. 13570 */ 13571 EXPORT_PC 13572 movl rSELF, %eax 13573 movl rPC, OUT_ARG0(%esp) 13574 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13575 movl rFP, OUT_ARG1(%esp) 13576 je 1f # reload rIBASE & resume if not 13577 movl %eax, OUT_ARG2(%esp) 13578 call dvmCheckBefore # (dPC, dFP, self) 13579 movl rSELF, %eax 135801: 13581 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13582 jmp *dvmAsmInstructionStart+(199*4) 13583 13584/* ------------------------------ */ 13585.L_ALT_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 13586/* File: x86/alt_stub.S */ 13587/* 13588 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13589 * any interesting requests and then jump to the real instruction 13590 * handler. Unlike the Arm handler, we can't do this as a tail call 13591 * because rIBASE is caller save and we need to reload it. 13592 * 13593 * Note that unlike in the Arm implementation, we should never arrive 13594 * here with a zero breakFlag because we always refresh rIBASE on 13595 * return. 13596 */ 13597 EXPORT_PC 13598 movl rSELF, %eax 13599 movl rPC, OUT_ARG0(%esp) 13600 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13601 movl rFP, OUT_ARG1(%esp) 13602 je 1f # reload rIBASE & resume if not 13603 movl %eax, OUT_ARG2(%esp) 13604 call dvmCheckBefore # (dPC, dFP, self) 13605 movl rSELF, %eax 136061: 13607 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13608 jmp *dvmAsmInstructionStart+(200*4) 13609 13610/* ------------------------------ */ 13611.L_ALT_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 13612/* File: x86/alt_stub.S */ 13613/* 13614 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13615 * any interesting requests and then jump to the real instruction 13616 * handler. Unlike the Arm handler, we can't do this as a tail call 13617 * because rIBASE is caller save and we need to reload it. 13618 * 13619 * Note that unlike in the Arm implementation, we should never arrive 13620 * here with a zero breakFlag because we always refresh rIBASE on 13621 * return. 13622 */ 13623 EXPORT_PC 13624 movl rSELF, %eax 13625 movl rPC, OUT_ARG0(%esp) 13626 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13627 movl rFP, OUT_ARG1(%esp) 13628 je 1f # reload rIBASE & resume if not 13629 movl %eax, OUT_ARG2(%esp) 13630 call dvmCheckBefore # (dPC, dFP, self) 13631 movl rSELF, %eax 136321: 13633 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13634 jmp *dvmAsmInstructionStart+(201*4) 13635 13636/* ------------------------------ */ 13637.L_ALT_OP_REM_FLOAT_2ADDR: /* 0xca */ 13638/* File: x86/alt_stub.S */ 13639/* 13640 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13641 * any interesting requests and then jump to the real instruction 13642 * handler. Unlike the Arm handler, we can't do this as a tail call 13643 * because rIBASE is caller save and we need to reload it. 13644 * 13645 * Note that unlike in the Arm implementation, we should never arrive 13646 * here with a zero breakFlag because we always refresh rIBASE on 13647 * return. 13648 */ 13649 EXPORT_PC 13650 movl rSELF, %eax 13651 movl rPC, OUT_ARG0(%esp) 13652 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13653 movl rFP, OUT_ARG1(%esp) 13654 je 1f # reload rIBASE & resume if not 13655 movl %eax, OUT_ARG2(%esp) 13656 call dvmCheckBefore # (dPC, dFP, self) 13657 movl rSELF, %eax 136581: 13659 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13660 jmp *dvmAsmInstructionStart+(202*4) 13661 13662/* ------------------------------ */ 13663.L_ALT_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 13664/* File: x86/alt_stub.S */ 13665/* 13666 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13667 * any interesting requests and then jump to the real instruction 13668 * handler. Unlike the Arm handler, we can't do this as a tail call 13669 * because rIBASE is caller save and we need to reload it. 13670 * 13671 * Note that unlike in the Arm implementation, we should never arrive 13672 * here with a zero breakFlag because we always refresh rIBASE on 13673 * return. 13674 */ 13675 EXPORT_PC 13676 movl rSELF, %eax 13677 movl rPC, OUT_ARG0(%esp) 13678 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13679 movl rFP, OUT_ARG1(%esp) 13680 je 1f # reload rIBASE & resume if not 13681 movl %eax, OUT_ARG2(%esp) 13682 call dvmCheckBefore # (dPC, dFP, self) 13683 movl rSELF, %eax 136841: 13685 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13686 jmp *dvmAsmInstructionStart+(203*4) 13687 13688/* ------------------------------ */ 13689.L_ALT_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 13690/* File: x86/alt_stub.S */ 13691/* 13692 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13693 * any interesting requests and then jump to the real instruction 13694 * handler. Unlike the Arm handler, we can't do this as a tail call 13695 * because rIBASE is caller save and we need to reload it. 13696 * 13697 * Note that unlike in the Arm implementation, we should never arrive 13698 * here with a zero breakFlag because we always refresh rIBASE on 13699 * return. 13700 */ 13701 EXPORT_PC 13702 movl rSELF, %eax 13703 movl rPC, OUT_ARG0(%esp) 13704 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13705 movl rFP, OUT_ARG1(%esp) 13706 je 1f # reload rIBASE & resume if not 13707 movl %eax, OUT_ARG2(%esp) 13708 call dvmCheckBefore # (dPC, dFP, self) 13709 movl rSELF, %eax 137101: 13711 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13712 jmp *dvmAsmInstructionStart+(204*4) 13713 13714/* ------------------------------ */ 13715.L_ALT_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 13716/* File: x86/alt_stub.S */ 13717/* 13718 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13719 * any interesting requests and then jump to the real instruction 13720 * handler. Unlike the Arm handler, we can't do this as a tail call 13721 * because rIBASE is caller save and we need to reload it. 13722 * 13723 * Note that unlike in the Arm implementation, we should never arrive 13724 * here with a zero breakFlag because we always refresh rIBASE on 13725 * return. 13726 */ 13727 EXPORT_PC 13728 movl rSELF, %eax 13729 movl rPC, OUT_ARG0(%esp) 13730 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13731 movl rFP, OUT_ARG1(%esp) 13732 je 1f # reload rIBASE & resume if not 13733 movl %eax, OUT_ARG2(%esp) 13734 call dvmCheckBefore # (dPC, dFP, self) 13735 movl rSELF, %eax 137361: 13737 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13738 jmp *dvmAsmInstructionStart+(205*4) 13739 13740/* ------------------------------ */ 13741.L_ALT_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 13742/* File: x86/alt_stub.S */ 13743/* 13744 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13745 * any interesting requests and then jump to the real instruction 13746 * handler. Unlike the Arm handler, we can't do this as a tail call 13747 * because rIBASE is caller save and we need to reload it. 13748 * 13749 * Note that unlike in the Arm implementation, we should never arrive 13750 * here with a zero breakFlag because we always refresh rIBASE on 13751 * return. 13752 */ 13753 EXPORT_PC 13754 movl rSELF, %eax 13755 movl rPC, OUT_ARG0(%esp) 13756 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13757 movl rFP, OUT_ARG1(%esp) 13758 je 1f # reload rIBASE & resume if not 13759 movl %eax, OUT_ARG2(%esp) 13760 call dvmCheckBefore # (dPC, dFP, self) 13761 movl rSELF, %eax 137621: 13763 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13764 jmp *dvmAsmInstructionStart+(206*4) 13765 13766/* ------------------------------ */ 13767.L_ALT_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 13768/* File: x86/alt_stub.S */ 13769/* 13770 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13771 * any interesting requests and then jump to the real instruction 13772 * handler. Unlike the Arm handler, we can't do this as a tail call 13773 * because rIBASE is caller save and we need to reload it. 13774 * 13775 * Note that unlike in the Arm implementation, we should never arrive 13776 * here with a zero breakFlag because we always refresh rIBASE on 13777 * return. 13778 */ 13779 EXPORT_PC 13780 movl rSELF, %eax 13781 movl rPC, OUT_ARG0(%esp) 13782 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13783 movl rFP, OUT_ARG1(%esp) 13784 je 1f # reload rIBASE & resume if not 13785 movl %eax, OUT_ARG2(%esp) 13786 call dvmCheckBefore # (dPC, dFP, self) 13787 movl rSELF, %eax 137881: 13789 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13790 jmp *dvmAsmInstructionStart+(207*4) 13791 13792/* ------------------------------ */ 13793.L_ALT_OP_ADD_INT_LIT16: /* 0xd0 */ 13794/* File: x86/alt_stub.S */ 13795/* 13796 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13797 * any interesting requests and then jump to the real instruction 13798 * handler. Unlike the Arm handler, we can't do this as a tail call 13799 * because rIBASE is caller save and we need to reload it. 13800 * 13801 * Note that unlike in the Arm implementation, we should never arrive 13802 * here with a zero breakFlag because we always refresh rIBASE on 13803 * return. 13804 */ 13805 EXPORT_PC 13806 movl rSELF, %eax 13807 movl rPC, OUT_ARG0(%esp) 13808 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13809 movl rFP, OUT_ARG1(%esp) 13810 je 1f # reload rIBASE & resume if not 13811 movl %eax, OUT_ARG2(%esp) 13812 call dvmCheckBefore # (dPC, dFP, self) 13813 movl rSELF, %eax 138141: 13815 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13816 jmp *dvmAsmInstructionStart+(208*4) 13817 13818/* ------------------------------ */ 13819.L_ALT_OP_RSUB_INT: /* 0xd1 */ 13820/* File: x86/alt_stub.S */ 13821/* 13822 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13823 * any interesting requests and then jump to the real instruction 13824 * handler. Unlike the Arm handler, we can't do this as a tail call 13825 * because rIBASE is caller save and we need to reload it. 13826 * 13827 * Note that unlike in the Arm implementation, we should never arrive 13828 * here with a zero breakFlag because we always refresh rIBASE on 13829 * return. 13830 */ 13831 EXPORT_PC 13832 movl rSELF, %eax 13833 movl rPC, OUT_ARG0(%esp) 13834 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13835 movl rFP, OUT_ARG1(%esp) 13836 je 1f # reload rIBASE & resume if not 13837 movl %eax, OUT_ARG2(%esp) 13838 call dvmCheckBefore # (dPC, dFP, self) 13839 movl rSELF, %eax 138401: 13841 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13842 jmp *dvmAsmInstructionStart+(209*4) 13843 13844/* ------------------------------ */ 13845.L_ALT_OP_MUL_INT_LIT16: /* 0xd2 */ 13846/* File: x86/alt_stub.S */ 13847/* 13848 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13849 * any interesting requests and then jump to the real instruction 13850 * handler. Unlike the Arm handler, we can't do this as a tail call 13851 * because rIBASE is caller save and we need to reload it. 13852 * 13853 * Note that unlike in the Arm implementation, we should never arrive 13854 * here with a zero breakFlag because we always refresh rIBASE on 13855 * return. 13856 */ 13857 EXPORT_PC 13858 movl rSELF, %eax 13859 movl rPC, OUT_ARG0(%esp) 13860 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13861 movl rFP, OUT_ARG1(%esp) 13862 je 1f # reload rIBASE & resume if not 13863 movl %eax, OUT_ARG2(%esp) 13864 call dvmCheckBefore # (dPC, dFP, self) 13865 movl rSELF, %eax 138661: 13867 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13868 jmp *dvmAsmInstructionStart+(210*4) 13869 13870/* ------------------------------ */ 13871.L_ALT_OP_DIV_INT_LIT16: /* 0xd3 */ 13872/* File: x86/alt_stub.S */ 13873/* 13874 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13875 * any interesting requests and then jump to the real instruction 13876 * handler. Unlike the Arm handler, we can't do this as a tail call 13877 * because rIBASE is caller save and we need to reload it. 13878 * 13879 * Note that unlike in the Arm implementation, we should never arrive 13880 * here with a zero breakFlag because we always refresh rIBASE on 13881 * return. 13882 */ 13883 EXPORT_PC 13884 movl rSELF, %eax 13885 movl rPC, OUT_ARG0(%esp) 13886 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13887 movl rFP, OUT_ARG1(%esp) 13888 je 1f # reload rIBASE & resume if not 13889 movl %eax, OUT_ARG2(%esp) 13890 call dvmCheckBefore # (dPC, dFP, self) 13891 movl rSELF, %eax 138921: 13893 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13894 jmp *dvmAsmInstructionStart+(211*4) 13895 13896/* ------------------------------ */ 13897.L_ALT_OP_REM_INT_LIT16: /* 0xd4 */ 13898/* File: x86/alt_stub.S */ 13899/* 13900 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13901 * any interesting requests and then jump to the real instruction 13902 * handler. Unlike the Arm handler, we can't do this as a tail call 13903 * because rIBASE is caller save and we need to reload it. 13904 * 13905 * Note that unlike in the Arm implementation, we should never arrive 13906 * here with a zero breakFlag because we always refresh rIBASE on 13907 * return. 13908 */ 13909 EXPORT_PC 13910 movl rSELF, %eax 13911 movl rPC, OUT_ARG0(%esp) 13912 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13913 movl rFP, OUT_ARG1(%esp) 13914 je 1f # reload rIBASE & resume if not 13915 movl %eax, OUT_ARG2(%esp) 13916 call dvmCheckBefore # (dPC, dFP, self) 13917 movl rSELF, %eax 139181: 13919 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13920 jmp *dvmAsmInstructionStart+(212*4) 13921 13922/* ------------------------------ */ 13923.L_ALT_OP_AND_INT_LIT16: /* 0xd5 */ 13924/* File: x86/alt_stub.S */ 13925/* 13926 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13927 * any interesting requests and then jump to the real instruction 13928 * handler. Unlike the Arm handler, we can't do this as a tail call 13929 * because rIBASE is caller save and we need to reload it. 13930 * 13931 * Note that unlike in the Arm implementation, we should never arrive 13932 * here with a zero breakFlag because we always refresh rIBASE on 13933 * return. 13934 */ 13935 EXPORT_PC 13936 movl rSELF, %eax 13937 movl rPC, OUT_ARG0(%esp) 13938 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13939 movl rFP, OUT_ARG1(%esp) 13940 je 1f # reload rIBASE & resume if not 13941 movl %eax, OUT_ARG2(%esp) 13942 call dvmCheckBefore # (dPC, dFP, self) 13943 movl rSELF, %eax 139441: 13945 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13946 jmp *dvmAsmInstructionStart+(213*4) 13947 13948/* ------------------------------ */ 13949.L_ALT_OP_OR_INT_LIT16: /* 0xd6 */ 13950/* File: x86/alt_stub.S */ 13951/* 13952 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13953 * any interesting requests and then jump to the real instruction 13954 * handler. Unlike the Arm handler, we can't do this as a tail call 13955 * because rIBASE is caller save and we need to reload it. 13956 * 13957 * Note that unlike in the Arm implementation, we should never arrive 13958 * here with a zero breakFlag because we always refresh rIBASE on 13959 * return. 13960 */ 13961 EXPORT_PC 13962 movl rSELF, %eax 13963 movl rPC, OUT_ARG0(%esp) 13964 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13965 movl rFP, OUT_ARG1(%esp) 13966 je 1f # reload rIBASE & resume if not 13967 movl %eax, OUT_ARG2(%esp) 13968 call dvmCheckBefore # (dPC, dFP, self) 13969 movl rSELF, %eax 139701: 13971 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13972 jmp *dvmAsmInstructionStart+(214*4) 13973 13974/* ------------------------------ */ 13975.L_ALT_OP_XOR_INT_LIT16: /* 0xd7 */ 13976/* File: x86/alt_stub.S */ 13977/* 13978 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13979 * any interesting requests and then jump to the real instruction 13980 * handler. Unlike the Arm handler, we can't do this as a tail call 13981 * because rIBASE is caller save and we need to reload it. 13982 * 13983 * Note that unlike in the Arm implementation, we should never arrive 13984 * here with a zero breakFlag because we always refresh rIBASE on 13985 * return. 13986 */ 13987 EXPORT_PC 13988 movl rSELF, %eax 13989 movl rPC, OUT_ARG0(%esp) 13990 cmpb $0,offThread_breakFlags(%eax) # anything to do? 13991 movl rFP, OUT_ARG1(%esp) 13992 je 1f # reload rIBASE & resume if not 13993 movl %eax, OUT_ARG2(%esp) 13994 call dvmCheckBefore # (dPC, dFP, self) 13995 movl rSELF, %eax 139961: 13997 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 13998 jmp *dvmAsmInstructionStart+(215*4) 13999 14000/* ------------------------------ */ 14001.L_ALT_OP_ADD_INT_LIT8: /* 0xd8 */ 14002/* File: x86/alt_stub.S */ 14003/* 14004 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14005 * any interesting requests and then jump to the real instruction 14006 * handler. Unlike the Arm handler, we can't do this as a tail call 14007 * because rIBASE is caller save and we need to reload it. 14008 * 14009 * Note that unlike in the Arm implementation, we should never arrive 14010 * here with a zero breakFlag because we always refresh rIBASE on 14011 * return. 14012 */ 14013 EXPORT_PC 14014 movl rSELF, %eax 14015 movl rPC, OUT_ARG0(%esp) 14016 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14017 movl rFP, OUT_ARG1(%esp) 14018 je 1f # reload rIBASE & resume if not 14019 movl %eax, OUT_ARG2(%esp) 14020 call dvmCheckBefore # (dPC, dFP, self) 14021 movl rSELF, %eax 140221: 14023 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14024 jmp *dvmAsmInstructionStart+(216*4) 14025 14026/* ------------------------------ */ 14027.L_ALT_OP_RSUB_INT_LIT8: /* 0xd9 */ 14028/* File: x86/alt_stub.S */ 14029/* 14030 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14031 * any interesting requests and then jump to the real instruction 14032 * handler. Unlike the Arm handler, we can't do this as a tail call 14033 * because rIBASE is caller save and we need to reload it. 14034 * 14035 * Note that unlike in the Arm implementation, we should never arrive 14036 * here with a zero breakFlag because we always refresh rIBASE on 14037 * return. 14038 */ 14039 EXPORT_PC 14040 movl rSELF, %eax 14041 movl rPC, OUT_ARG0(%esp) 14042 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14043 movl rFP, OUT_ARG1(%esp) 14044 je 1f # reload rIBASE & resume if not 14045 movl %eax, OUT_ARG2(%esp) 14046 call dvmCheckBefore # (dPC, dFP, self) 14047 movl rSELF, %eax 140481: 14049 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14050 jmp *dvmAsmInstructionStart+(217*4) 14051 14052/* ------------------------------ */ 14053.L_ALT_OP_MUL_INT_LIT8: /* 0xda */ 14054/* File: x86/alt_stub.S */ 14055/* 14056 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14057 * any interesting requests and then jump to the real instruction 14058 * handler. Unlike the Arm handler, we can't do this as a tail call 14059 * because rIBASE is caller save and we need to reload it. 14060 * 14061 * Note that unlike in the Arm implementation, we should never arrive 14062 * here with a zero breakFlag because we always refresh rIBASE on 14063 * return. 14064 */ 14065 EXPORT_PC 14066 movl rSELF, %eax 14067 movl rPC, OUT_ARG0(%esp) 14068 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14069 movl rFP, OUT_ARG1(%esp) 14070 je 1f # reload rIBASE & resume if not 14071 movl %eax, OUT_ARG2(%esp) 14072 call dvmCheckBefore # (dPC, dFP, self) 14073 movl rSELF, %eax 140741: 14075 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14076 jmp *dvmAsmInstructionStart+(218*4) 14077 14078/* ------------------------------ */ 14079.L_ALT_OP_DIV_INT_LIT8: /* 0xdb */ 14080/* File: x86/alt_stub.S */ 14081/* 14082 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14083 * any interesting requests and then jump to the real instruction 14084 * handler. Unlike the Arm handler, we can't do this as a tail call 14085 * because rIBASE is caller save and we need to reload it. 14086 * 14087 * Note that unlike in the Arm implementation, we should never arrive 14088 * here with a zero breakFlag because we always refresh rIBASE on 14089 * return. 14090 */ 14091 EXPORT_PC 14092 movl rSELF, %eax 14093 movl rPC, OUT_ARG0(%esp) 14094 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14095 movl rFP, OUT_ARG1(%esp) 14096 je 1f # reload rIBASE & resume if not 14097 movl %eax, OUT_ARG2(%esp) 14098 call dvmCheckBefore # (dPC, dFP, self) 14099 movl rSELF, %eax 141001: 14101 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14102 jmp *dvmAsmInstructionStart+(219*4) 14103 14104/* ------------------------------ */ 14105.L_ALT_OP_REM_INT_LIT8: /* 0xdc */ 14106/* File: x86/alt_stub.S */ 14107/* 14108 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14109 * any interesting requests and then jump to the real instruction 14110 * handler. Unlike the Arm handler, we can't do this as a tail call 14111 * because rIBASE is caller save and we need to reload it. 14112 * 14113 * Note that unlike in the Arm implementation, we should never arrive 14114 * here with a zero breakFlag because we always refresh rIBASE on 14115 * return. 14116 */ 14117 EXPORT_PC 14118 movl rSELF, %eax 14119 movl rPC, OUT_ARG0(%esp) 14120 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14121 movl rFP, OUT_ARG1(%esp) 14122 je 1f # reload rIBASE & resume if not 14123 movl %eax, OUT_ARG2(%esp) 14124 call dvmCheckBefore # (dPC, dFP, self) 14125 movl rSELF, %eax 141261: 14127 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14128 jmp *dvmAsmInstructionStart+(220*4) 14129 14130/* ------------------------------ */ 14131.L_ALT_OP_AND_INT_LIT8: /* 0xdd */ 14132/* File: x86/alt_stub.S */ 14133/* 14134 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14135 * any interesting requests and then jump to the real instruction 14136 * handler. Unlike the Arm handler, we can't do this as a tail call 14137 * because rIBASE is caller save and we need to reload it. 14138 * 14139 * Note that unlike in the Arm implementation, we should never arrive 14140 * here with a zero breakFlag because we always refresh rIBASE on 14141 * return. 14142 */ 14143 EXPORT_PC 14144 movl rSELF, %eax 14145 movl rPC, OUT_ARG0(%esp) 14146 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14147 movl rFP, OUT_ARG1(%esp) 14148 je 1f # reload rIBASE & resume if not 14149 movl %eax, OUT_ARG2(%esp) 14150 call dvmCheckBefore # (dPC, dFP, self) 14151 movl rSELF, %eax 141521: 14153 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14154 jmp *dvmAsmInstructionStart+(221*4) 14155 14156/* ------------------------------ */ 14157.L_ALT_OP_OR_INT_LIT8: /* 0xde */ 14158/* File: x86/alt_stub.S */ 14159/* 14160 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14161 * any interesting requests and then jump to the real instruction 14162 * handler. Unlike the Arm handler, we can't do this as a tail call 14163 * because rIBASE is caller save and we need to reload it. 14164 * 14165 * Note that unlike in the Arm implementation, we should never arrive 14166 * here with a zero breakFlag because we always refresh rIBASE on 14167 * return. 14168 */ 14169 EXPORT_PC 14170 movl rSELF, %eax 14171 movl rPC, OUT_ARG0(%esp) 14172 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14173 movl rFP, OUT_ARG1(%esp) 14174 je 1f # reload rIBASE & resume if not 14175 movl %eax, OUT_ARG2(%esp) 14176 call dvmCheckBefore # (dPC, dFP, self) 14177 movl rSELF, %eax 141781: 14179 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14180 jmp *dvmAsmInstructionStart+(222*4) 14181 14182/* ------------------------------ */ 14183.L_ALT_OP_XOR_INT_LIT8: /* 0xdf */ 14184/* File: x86/alt_stub.S */ 14185/* 14186 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14187 * any interesting requests and then jump to the real instruction 14188 * handler. Unlike the Arm handler, we can't do this as a tail call 14189 * because rIBASE is caller save and we need to reload it. 14190 * 14191 * Note that unlike in the Arm implementation, we should never arrive 14192 * here with a zero breakFlag because we always refresh rIBASE on 14193 * return. 14194 */ 14195 EXPORT_PC 14196 movl rSELF, %eax 14197 movl rPC, OUT_ARG0(%esp) 14198 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14199 movl rFP, OUT_ARG1(%esp) 14200 je 1f # reload rIBASE & resume if not 14201 movl %eax, OUT_ARG2(%esp) 14202 call dvmCheckBefore # (dPC, dFP, self) 14203 movl rSELF, %eax 142041: 14205 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14206 jmp *dvmAsmInstructionStart+(223*4) 14207 14208/* ------------------------------ */ 14209.L_ALT_OP_SHL_INT_LIT8: /* 0xe0 */ 14210/* File: x86/alt_stub.S */ 14211/* 14212 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14213 * any interesting requests and then jump to the real instruction 14214 * handler. Unlike the Arm handler, we can't do this as a tail call 14215 * because rIBASE is caller save and we need to reload it. 14216 * 14217 * Note that unlike in the Arm implementation, we should never arrive 14218 * here with a zero breakFlag because we always refresh rIBASE on 14219 * return. 14220 */ 14221 EXPORT_PC 14222 movl rSELF, %eax 14223 movl rPC, OUT_ARG0(%esp) 14224 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14225 movl rFP, OUT_ARG1(%esp) 14226 je 1f # reload rIBASE & resume if not 14227 movl %eax, OUT_ARG2(%esp) 14228 call dvmCheckBefore # (dPC, dFP, self) 14229 movl rSELF, %eax 142301: 14231 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14232 jmp *dvmAsmInstructionStart+(224*4) 14233 14234/* ------------------------------ */ 14235.L_ALT_OP_SHR_INT_LIT8: /* 0xe1 */ 14236/* File: x86/alt_stub.S */ 14237/* 14238 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14239 * any interesting requests and then jump to the real instruction 14240 * handler. Unlike the Arm handler, we can't do this as a tail call 14241 * because rIBASE is caller save and we need to reload it. 14242 * 14243 * Note that unlike in the Arm implementation, we should never arrive 14244 * here with a zero breakFlag because we always refresh rIBASE on 14245 * return. 14246 */ 14247 EXPORT_PC 14248 movl rSELF, %eax 14249 movl rPC, OUT_ARG0(%esp) 14250 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14251 movl rFP, OUT_ARG1(%esp) 14252 je 1f # reload rIBASE & resume if not 14253 movl %eax, OUT_ARG2(%esp) 14254 call dvmCheckBefore # (dPC, dFP, self) 14255 movl rSELF, %eax 142561: 14257 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14258 jmp *dvmAsmInstructionStart+(225*4) 14259 14260/* ------------------------------ */ 14261.L_ALT_OP_USHR_INT_LIT8: /* 0xe2 */ 14262/* File: x86/alt_stub.S */ 14263/* 14264 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14265 * any interesting requests and then jump to the real instruction 14266 * handler. Unlike the Arm handler, we can't do this as a tail call 14267 * because rIBASE is caller save and we need to reload it. 14268 * 14269 * Note that unlike in the Arm implementation, we should never arrive 14270 * here with a zero breakFlag because we always refresh rIBASE on 14271 * return. 14272 */ 14273 EXPORT_PC 14274 movl rSELF, %eax 14275 movl rPC, OUT_ARG0(%esp) 14276 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14277 movl rFP, OUT_ARG1(%esp) 14278 je 1f # reload rIBASE & resume if not 14279 movl %eax, OUT_ARG2(%esp) 14280 call dvmCheckBefore # (dPC, dFP, self) 14281 movl rSELF, %eax 142821: 14283 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14284 jmp *dvmAsmInstructionStart+(226*4) 14285 14286/* ------------------------------ */ 14287.L_ALT_OP_IGET_VOLATILE: /* 0xe3 */ 14288/* File: x86/alt_stub.S */ 14289/* 14290 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14291 * any interesting requests and then jump to the real instruction 14292 * handler. Unlike the Arm handler, we can't do this as a tail call 14293 * because rIBASE is caller save and we need to reload it. 14294 * 14295 * Note that unlike in the Arm implementation, we should never arrive 14296 * here with a zero breakFlag because we always refresh rIBASE on 14297 * return. 14298 */ 14299 EXPORT_PC 14300 movl rSELF, %eax 14301 movl rPC, OUT_ARG0(%esp) 14302 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14303 movl rFP, OUT_ARG1(%esp) 14304 je 1f # reload rIBASE & resume if not 14305 movl %eax, OUT_ARG2(%esp) 14306 call dvmCheckBefore # (dPC, dFP, self) 14307 movl rSELF, %eax 143081: 14309 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14310 jmp *dvmAsmInstructionStart+(227*4) 14311 14312/* ------------------------------ */ 14313.L_ALT_OP_IPUT_VOLATILE: /* 0xe4 */ 14314/* File: x86/alt_stub.S */ 14315/* 14316 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14317 * any interesting requests and then jump to the real instruction 14318 * handler. Unlike the Arm handler, we can't do this as a tail call 14319 * because rIBASE is caller save and we need to reload it. 14320 * 14321 * Note that unlike in the Arm implementation, we should never arrive 14322 * here with a zero breakFlag because we always refresh rIBASE on 14323 * return. 14324 */ 14325 EXPORT_PC 14326 movl rSELF, %eax 14327 movl rPC, OUT_ARG0(%esp) 14328 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14329 movl rFP, OUT_ARG1(%esp) 14330 je 1f # reload rIBASE & resume if not 14331 movl %eax, OUT_ARG2(%esp) 14332 call dvmCheckBefore # (dPC, dFP, self) 14333 movl rSELF, %eax 143341: 14335 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14336 jmp *dvmAsmInstructionStart+(228*4) 14337 14338/* ------------------------------ */ 14339.L_ALT_OP_SGET_VOLATILE: /* 0xe5 */ 14340/* File: x86/alt_stub.S */ 14341/* 14342 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14343 * any interesting requests and then jump to the real instruction 14344 * handler. Unlike the Arm handler, we can't do this as a tail call 14345 * because rIBASE is caller save and we need to reload it. 14346 * 14347 * Note that unlike in the Arm implementation, we should never arrive 14348 * here with a zero breakFlag because we always refresh rIBASE on 14349 * return. 14350 */ 14351 EXPORT_PC 14352 movl rSELF, %eax 14353 movl rPC, OUT_ARG0(%esp) 14354 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14355 movl rFP, OUT_ARG1(%esp) 14356 je 1f # reload rIBASE & resume if not 14357 movl %eax, OUT_ARG2(%esp) 14358 call dvmCheckBefore # (dPC, dFP, self) 14359 movl rSELF, %eax 143601: 14361 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14362 jmp *dvmAsmInstructionStart+(229*4) 14363 14364/* ------------------------------ */ 14365.L_ALT_OP_SPUT_VOLATILE: /* 0xe6 */ 14366/* File: x86/alt_stub.S */ 14367/* 14368 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14369 * any interesting requests and then jump to the real instruction 14370 * handler. Unlike the Arm handler, we can't do this as a tail call 14371 * because rIBASE is caller save and we need to reload it. 14372 * 14373 * Note that unlike in the Arm implementation, we should never arrive 14374 * here with a zero breakFlag because we always refresh rIBASE on 14375 * return. 14376 */ 14377 EXPORT_PC 14378 movl rSELF, %eax 14379 movl rPC, OUT_ARG0(%esp) 14380 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14381 movl rFP, OUT_ARG1(%esp) 14382 je 1f # reload rIBASE & resume if not 14383 movl %eax, OUT_ARG2(%esp) 14384 call dvmCheckBefore # (dPC, dFP, self) 14385 movl rSELF, %eax 143861: 14387 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14388 jmp *dvmAsmInstructionStart+(230*4) 14389 14390/* ------------------------------ */ 14391.L_ALT_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 14392/* File: x86/alt_stub.S */ 14393/* 14394 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14395 * any interesting requests and then jump to the real instruction 14396 * handler. Unlike the Arm handler, we can't do this as a tail call 14397 * because rIBASE is caller save and we need to reload it. 14398 * 14399 * Note that unlike in the Arm implementation, we should never arrive 14400 * here with a zero breakFlag because we always refresh rIBASE on 14401 * return. 14402 */ 14403 EXPORT_PC 14404 movl rSELF, %eax 14405 movl rPC, OUT_ARG0(%esp) 14406 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14407 movl rFP, OUT_ARG1(%esp) 14408 je 1f # reload rIBASE & resume if not 14409 movl %eax, OUT_ARG2(%esp) 14410 call dvmCheckBefore # (dPC, dFP, self) 14411 movl rSELF, %eax 144121: 14413 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14414 jmp *dvmAsmInstructionStart+(231*4) 14415 14416/* ------------------------------ */ 14417.L_ALT_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 14418/* File: x86/alt_stub.S */ 14419/* 14420 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14421 * any interesting requests and then jump to the real instruction 14422 * handler. Unlike the Arm handler, we can't do this as a tail call 14423 * because rIBASE is caller save and we need to reload it. 14424 * 14425 * Note that unlike in the Arm implementation, we should never arrive 14426 * here with a zero breakFlag because we always refresh rIBASE on 14427 * return. 14428 */ 14429 EXPORT_PC 14430 movl rSELF, %eax 14431 movl rPC, OUT_ARG0(%esp) 14432 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14433 movl rFP, OUT_ARG1(%esp) 14434 je 1f # reload rIBASE & resume if not 14435 movl %eax, OUT_ARG2(%esp) 14436 call dvmCheckBefore # (dPC, dFP, self) 14437 movl rSELF, %eax 144381: 14439 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14440 jmp *dvmAsmInstructionStart+(232*4) 14441 14442/* ------------------------------ */ 14443.L_ALT_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 14444/* File: x86/alt_stub.S */ 14445/* 14446 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14447 * any interesting requests and then jump to the real instruction 14448 * handler. Unlike the Arm handler, we can't do this as a tail call 14449 * because rIBASE is caller save and we need to reload it. 14450 * 14451 * Note that unlike in the Arm implementation, we should never arrive 14452 * here with a zero breakFlag because we always refresh rIBASE on 14453 * return. 14454 */ 14455 EXPORT_PC 14456 movl rSELF, %eax 14457 movl rPC, OUT_ARG0(%esp) 14458 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14459 movl rFP, OUT_ARG1(%esp) 14460 je 1f # reload rIBASE & resume if not 14461 movl %eax, OUT_ARG2(%esp) 14462 call dvmCheckBefore # (dPC, dFP, self) 14463 movl rSELF, %eax 144641: 14465 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14466 jmp *dvmAsmInstructionStart+(233*4) 14467 14468/* ------------------------------ */ 14469.L_ALT_OP_SGET_WIDE_VOLATILE: /* 0xea */ 14470/* File: x86/alt_stub.S */ 14471/* 14472 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14473 * any interesting requests and then jump to the real instruction 14474 * handler. Unlike the Arm handler, we can't do this as a tail call 14475 * because rIBASE is caller save and we need to reload it. 14476 * 14477 * Note that unlike in the Arm implementation, we should never arrive 14478 * here with a zero breakFlag because we always refresh rIBASE on 14479 * return. 14480 */ 14481 EXPORT_PC 14482 movl rSELF, %eax 14483 movl rPC, OUT_ARG0(%esp) 14484 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14485 movl rFP, OUT_ARG1(%esp) 14486 je 1f # reload rIBASE & resume if not 14487 movl %eax, OUT_ARG2(%esp) 14488 call dvmCheckBefore # (dPC, dFP, self) 14489 movl rSELF, %eax 144901: 14491 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14492 jmp *dvmAsmInstructionStart+(234*4) 14493 14494/* ------------------------------ */ 14495.L_ALT_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 14496/* File: x86/alt_stub.S */ 14497/* 14498 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14499 * any interesting requests and then jump to the real instruction 14500 * handler. Unlike the Arm handler, we can't do this as a tail call 14501 * because rIBASE is caller save and we need to reload it. 14502 * 14503 * Note that unlike in the Arm implementation, we should never arrive 14504 * here with a zero breakFlag because we always refresh rIBASE on 14505 * return. 14506 */ 14507 EXPORT_PC 14508 movl rSELF, %eax 14509 movl rPC, OUT_ARG0(%esp) 14510 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14511 movl rFP, OUT_ARG1(%esp) 14512 je 1f # reload rIBASE & resume if not 14513 movl %eax, OUT_ARG2(%esp) 14514 call dvmCheckBefore # (dPC, dFP, self) 14515 movl rSELF, %eax 145161: 14517 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14518 jmp *dvmAsmInstructionStart+(235*4) 14519 14520/* ------------------------------ */ 14521.L_ALT_OP_BREAKPOINT: /* 0xec */ 14522/* File: x86/alt_stub.S */ 14523/* 14524 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14525 * any interesting requests and then jump to the real instruction 14526 * handler. Unlike the Arm handler, we can't do this as a tail call 14527 * because rIBASE is caller save and we need to reload it. 14528 * 14529 * Note that unlike in the Arm implementation, we should never arrive 14530 * here with a zero breakFlag because we always refresh rIBASE on 14531 * return. 14532 */ 14533 EXPORT_PC 14534 movl rSELF, %eax 14535 movl rPC, OUT_ARG0(%esp) 14536 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14537 movl rFP, OUT_ARG1(%esp) 14538 je 1f # reload rIBASE & resume if not 14539 movl %eax, OUT_ARG2(%esp) 14540 call dvmCheckBefore # (dPC, dFP, self) 14541 movl rSELF, %eax 145421: 14543 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14544 jmp *dvmAsmInstructionStart+(236*4) 14545 14546/* ------------------------------ */ 14547.L_ALT_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 14548/* File: x86/alt_stub.S */ 14549/* 14550 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14551 * any interesting requests and then jump to the real instruction 14552 * handler. Unlike the Arm handler, we can't do this as a tail call 14553 * because rIBASE is caller save and we need to reload it. 14554 * 14555 * Note that unlike in the Arm implementation, we should never arrive 14556 * here with a zero breakFlag because we always refresh rIBASE on 14557 * return. 14558 */ 14559 EXPORT_PC 14560 movl rSELF, %eax 14561 movl rPC, OUT_ARG0(%esp) 14562 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14563 movl rFP, OUT_ARG1(%esp) 14564 je 1f # reload rIBASE & resume if not 14565 movl %eax, OUT_ARG2(%esp) 14566 call dvmCheckBefore # (dPC, dFP, self) 14567 movl rSELF, %eax 145681: 14569 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14570 jmp *dvmAsmInstructionStart+(237*4) 14571 14572/* ------------------------------ */ 14573.L_ALT_OP_EXECUTE_INLINE: /* 0xee */ 14574/* File: x86/alt_stub.S */ 14575/* 14576 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14577 * any interesting requests and then jump to the real instruction 14578 * handler. Unlike the Arm handler, we can't do this as a tail call 14579 * because rIBASE is caller save and we need to reload it. 14580 * 14581 * Note that unlike in the Arm implementation, we should never arrive 14582 * here with a zero breakFlag because we always refresh rIBASE on 14583 * return. 14584 */ 14585 EXPORT_PC 14586 movl rSELF, %eax 14587 movl rPC, OUT_ARG0(%esp) 14588 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14589 movl rFP, OUT_ARG1(%esp) 14590 je 1f # reload rIBASE & resume if not 14591 movl %eax, OUT_ARG2(%esp) 14592 call dvmCheckBefore # (dPC, dFP, self) 14593 movl rSELF, %eax 145941: 14595 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14596 jmp *dvmAsmInstructionStart+(238*4) 14597 14598/* ------------------------------ */ 14599.L_ALT_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 14600/* File: x86/alt_stub.S */ 14601/* 14602 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14603 * any interesting requests and then jump to the real instruction 14604 * handler. Unlike the Arm handler, we can't do this as a tail call 14605 * because rIBASE is caller save and we need to reload it. 14606 * 14607 * Note that unlike in the Arm implementation, we should never arrive 14608 * here with a zero breakFlag because we always refresh rIBASE on 14609 * return. 14610 */ 14611 EXPORT_PC 14612 movl rSELF, %eax 14613 movl rPC, OUT_ARG0(%esp) 14614 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14615 movl rFP, OUT_ARG1(%esp) 14616 je 1f # reload rIBASE & resume if not 14617 movl %eax, OUT_ARG2(%esp) 14618 call dvmCheckBefore # (dPC, dFP, self) 14619 movl rSELF, %eax 146201: 14621 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14622 jmp *dvmAsmInstructionStart+(239*4) 14623 14624/* ------------------------------ */ 14625.L_ALT_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */ 14626/* File: x86/alt_stub.S */ 14627/* 14628 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14629 * any interesting requests and then jump to the real instruction 14630 * handler. Unlike the Arm handler, we can't do this as a tail call 14631 * because rIBASE is caller save and we need to reload it. 14632 * 14633 * Note that unlike in the Arm implementation, we should never arrive 14634 * here with a zero breakFlag because we always refresh rIBASE on 14635 * return. 14636 */ 14637 EXPORT_PC 14638 movl rSELF, %eax 14639 movl rPC, OUT_ARG0(%esp) 14640 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14641 movl rFP, OUT_ARG1(%esp) 14642 je 1f # reload rIBASE & resume if not 14643 movl %eax, OUT_ARG2(%esp) 14644 call dvmCheckBefore # (dPC, dFP, self) 14645 movl rSELF, %eax 146461: 14647 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14648 jmp *dvmAsmInstructionStart+(240*4) 14649 14650/* ------------------------------ */ 14651.L_ALT_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 14652/* File: x86/alt_stub.S */ 14653/* 14654 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14655 * any interesting requests and then jump to the real instruction 14656 * handler. Unlike the Arm handler, we can't do this as a tail call 14657 * because rIBASE is caller save and we need to reload it. 14658 * 14659 * Note that unlike in the Arm implementation, we should never arrive 14660 * here with a zero breakFlag because we always refresh rIBASE on 14661 * return. 14662 */ 14663 EXPORT_PC 14664 movl rSELF, %eax 14665 movl rPC, OUT_ARG0(%esp) 14666 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14667 movl rFP, OUT_ARG1(%esp) 14668 je 1f # reload rIBASE & resume if not 14669 movl %eax, OUT_ARG2(%esp) 14670 call dvmCheckBefore # (dPC, dFP, self) 14671 movl rSELF, %eax 146721: 14673 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14674 jmp *dvmAsmInstructionStart+(241*4) 14675 14676/* ------------------------------ */ 14677.L_ALT_OP_IGET_QUICK: /* 0xf2 */ 14678/* File: x86/alt_stub.S */ 14679/* 14680 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14681 * any interesting requests and then jump to the real instruction 14682 * handler. Unlike the Arm handler, we can't do this as a tail call 14683 * because rIBASE is caller save and we need to reload it. 14684 * 14685 * Note that unlike in the Arm implementation, we should never arrive 14686 * here with a zero breakFlag because we always refresh rIBASE on 14687 * return. 14688 */ 14689 EXPORT_PC 14690 movl rSELF, %eax 14691 movl rPC, OUT_ARG0(%esp) 14692 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14693 movl rFP, OUT_ARG1(%esp) 14694 je 1f # reload rIBASE & resume if not 14695 movl %eax, OUT_ARG2(%esp) 14696 call dvmCheckBefore # (dPC, dFP, self) 14697 movl rSELF, %eax 146981: 14699 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14700 jmp *dvmAsmInstructionStart+(242*4) 14701 14702/* ------------------------------ */ 14703.L_ALT_OP_IGET_WIDE_QUICK: /* 0xf3 */ 14704/* File: x86/alt_stub.S */ 14705/* 14706 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14707 * any interesting requests and then jump to the real instruction 14708 * handler. Unlike the Arm handler, we can't do this as a tail call 14709 * because rIBASE is caller save and we need to reload it. 14710 * 14711 * Note that unlike in the Arm implementation, we should never arrive 14712 * here with a zero breakFlag because we always refresh rIBASE on 14713 * return. 14714 */ 14715 EXPORT_PC 14716 movl rSELF, %eax 14717 movl rPC, OUT_ARG0(%esp) 14718 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14719 movl rFP, OUT_ARG1(%esp) 14720 je 1f # reload rIBASE & resume if not 14721 movl %eax, OUT_ARG2(%esp) 14722 call dvmCheckBefore # (dPC, dFP, self) 14723 movl rSELF, %eax 147241: 14725 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14726 jmp *dvmAsmInstructionStart+(243*4) 14727 14728/* ------------------------------ */ 14729.L_ALT_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 14730/* File: x86/alt_stub.S */ 14731/* 14732 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14733 * any interesting requests and then jump to the real instruction 14734 * handler. Unlike the Arm handler, we can't do this as a tail call 14735 * because rIBASE is caller save and we need to reload it. 14736 * 14737 * Note that unlike in the Arm implementation, we should never arrive 14738 * here with a zero breakFlag because we always refresh rIBASE on 14739 * return. 14740 */ 14741 EXPORT_PC 14742 movl rSELF, %eax 14743 movl rPC, OUT_ARG0(%esp) 14744 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14745 movl rFP, OUT_ARG1(%esp) 14746 je 1f # reload rIBASE & resume if not 14747 movl %eax, OUT_ARG2(%esp) 14748 call dvmCheckBefore # (dPC, dFP, self) 14749 movl rSELF, %eax 147501: 14751 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14752 jmp *dvmAsmInstructionStart+(244*4) 14753 14754/* ------------------------------ */ 14755.L_ALT_OP_IPUT_QUICK: /* 0xf5 */ 14756/* File: x86/alt_stub.S */ 14757/* 14758 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14759 * any interesting requests and then jump to the real instruction 14760 * handler. Unlike the Arm handler, we can't do this as a tail call 14761 * because rIBASE is caller save and we need to reload it. 14762 * 14763 * Note that unlike in the Arm implementation, we should never arrive 14764 * here with a zero breakFlag because we always refresh rIBASE on 14765 * return. 14766 */ 14767 EXPORT_PC 14768 movl rSELF, %eax 14769 movl rPC, OUT_ARG0(%esp) 14770 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14771 movl rFP, OUT_ARG1(%esp) 14772 je 1f # reload rIBASE & resume if not 14773 movl %eax, OUT_ARG2(%esp) 14774 call dvmCheckBefore # (dPC, dFP, self) 14775 movl rSELF, %eax 147761: 14777 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14778 jmp *dvmAsmInstructionStart+(245*4) 14779 14780/* ------------------------------ */ 14781.L_ALT_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 14782/* File: x86/alt_stub.S */ 14783/* 14784 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14785 * any interesting requests and then jump to the real instruction 14786 * handler. Unlike the Arm handler, we can't do this as a tail call 14787 * because rIBASE is caller save and we need to reload it. 14788 * 14789 * Note that unlike in the Arm implementation, we should never arrive 14790 * here with a zero breakFlag because we always refresh rIBASE on 14791 * return. 14792 */ 14793 EXPORT_PC 14794 movl rSELF, %eax 14795 movl rPC, OUT_ARG0(%esp) 14796 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14797 movl rFP, OUT_ARG1(%esp) 14798 je 1f # reload rIBASE & resume if not 14799 movl %eax, OUT_ARG2(%esp) 14800 call dvmCheckBefore # (dPC, dFP, self) 14801 movl rSELF, %eax 148021: 14803 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14804 jmp *dvmAsmInstructionStart+(246*4) 14805 14806/* ------------------------------ */ 14807.L_ALT_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 14808/* File: x86/alt_stub.S */ 14809/* 14810 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14811 * any interesting requests and then jump to the real instruction 14812 * handler. Unlike the Arm handler, we can't do this as a tail call 14813 * because rIBASE is caller save and we need to reload it. 14814 * 14815 * Note that unlike in the Arm implementation, we should never arrive 14816 * here with a zero breakFlag because we always refresh rIBASE on 14817 * return. 14818 */ 14819 EXPORT_PC 14820 movl rSELF, %eax 14821 movl rPC, OUT_ARG0(%esp) 14822 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14823 movl rFP, OUT_ARG1(%esp) 14824 je 1f # reload rIBASE & resume if not 14825 movl %eax, OUT_ARG2(%esp) 14826 call dvmCheckBefore # (dPC, dFP, self) 14827 movl rSELF, %eax 148281: 14829 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14830 jmp *dvmAsmInstructionStart+(247*4) 14831 14832/* ------------------------------ */ 14833.L_ALT_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 14834/* File: x86/alt_stub.S */ 14835/* 14836 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14837 * any interesting requests and then jump to the real instruction 14838 * handler. Unlike the Arm handler, we can't do this as a tail call 14839 * because rIBASE is caller save and we need to reload it. 14840 * 14841 * Note that unlike in the Arm implementation, we should never arrive 14842 * here with a zero breakFlag because we always refresh rIBASE on 14843 * return. 14844 */ 14845 EXPORT_PC 14846 movl rSELF, %eax 14847 movl rPC, OUT_ARG0(%esp) 14848 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14849 movl rFP, OUT_ARG1(%esp) 14850 je 1f # reload rIBASE & resume if not 14851 movl %eax, OUT_ARG2(%esp) 14852 call dvmCheckBefore # (dPC, dFP, self) 14853 movl rSELF, %eax 148541: 14855 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14856 jmp *dvmAsmInstructionStart+(248*4) 14857 14858/* ------------------------------ */ 14859.L_ALT_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 14860/* File: x86/alt_stub.S */ 14861/* 14862 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14863 * any interesting requests and then jump to the real instruction 14864 * handler. Unlike the Arm handler, we can't do this as a tail call 14865 * because rIBASE is caller save and we need to reload it. 14866 * 14867 * Note that unlike in the Arm implementation, we should never arrive 14868 * here with a zero breakFlag because we always refresh rIBASE on 14869 * return. 14870 */ 14871 EXPORT_PC 14872 movl rSELF, %eax 14873 movl rPC, OUT_ARG0(%esp) 14874 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14875 movl rFP, OUT_ARG1(%esp) 14876 je 1f # reload rIBASE & resume if not 14877 movl %eax, OUT_ARG2(%esp) 14878 call dvmCheckBefore # (dPC, dFP, self) 14879 movl rSELF, %eax 148801: 14881 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14882 jmp *dvmAsmInstructionStart+(249*4) 14883 14884/* ------------------------------ */ 14885.L_ALT_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 14886/* File: x86/alt_stub.S */ 14887/* 14888 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14889 * any interesting requests and then jump to the real instruction 14890 * handler. Unlike the Arm handler, we can't do this as a tail call 14891 * because rIBASE is caller save and we need to reload it. 14892 * 14893 * Note that unlike in the Arm implementation, we should never arrive 14894 * here with a zero breakFlag because we always refresh rIBASE on 14895 * return. 14896 */ 14897 EXPORT_PC 14898 movl rSELF, %eax 14899 movl rPC, OUT_ARG0(%esp) 14900 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14901 movl rFP, OUT_ARG1(%esp) 14902 je 1f # reload rIBASE & resume if not 14903 movl %eax, OUT_ARG2(%esp) 14904 call dvmCheckBefore # (dPC, dFP, self) 14905 movl rSELF, %eax 149061: 14907 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14908 jmp *dvmAsmInstructionStart+(250*4) 14909 14910/* ------------------------------ */ 14911.L_ALT_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 14912/* File: x86/alt_stub.S */ 14913/* 14914 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14915 * any interesting requests and then jump to the real instruction 14916 * handler. Unlike the Arm handler, we can't do this as a tail call 14917 * because rIBASE is caller save and we need to reload it. 14918 * 14919 * Note that unlike in the Arm implementation, we should never arrive 14920 * here with a zero breakFlag because we always refresh rIBASE on 14921 * return. 14922 */ 14923 EXPORT_PC 14924 movl rSELF, %eax 14925 movl rPC, OUT_ARG0(%esp) 14926 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14927 movl rFP, OUT_ARG1(%esp) 14928 je 1f # reload rIBASE & resume if not 14929 movl %eax, OUT_ARG2(%esp) 14930 call dvmCheckBefore # (dPC, dFP, self) 14931 movl rSELF, %eax 149321: 14933 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14934 jmp *dvmAsmInstructionStart+(251*4) 14935 14936/* ------------------------------ */ 14937.L_ALT_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 14938/* File: x86/alt_stub.S */ 14939/* 14940 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14941 * any interesting requests and then jump to the real instruction 14942 * handler. Unlike the Arm handler, we can't do this as a tail call 14943 * because rIBASE is caller save and we need to reload it. 14944 * 14945 * Note that unlike in the Arm implementation, we should never arrive 14946 * here with a zero breakFlag because we always refresh rIBASE on 14947 * return. 14948 */ 14949 EXPORT_PC 14950 movl rSELF, %eax 14951 movl rPC, OUT_ARG0(%esp) 14952 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14953 movl rFP, OUT_ARG1(%esp) 14954 je 1f # reload rIBASE & resume if not 14955 movl %eax, OUT_ARG2(%esp) 14956 call dvmCheckBefore # (dPC, dFP, self) 14957 movl rSELF, %eax 149581: 14959 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14960 jmp *dvmAsmInstructionStart+(252*4) 14961 14962/* ------------------------------ */ 14963.L_ALT_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 14964/* File: x86/alt_stub.S */ 14965/* 14966 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14967 * any interesting requests and then jump to the real instruction 14968 * handler. Unlike the Arm handler, we can't do this as a tail call 14969 * because rIBASE is caller save and we need to reload it. 14970 * 14971 * Note that unlike in the Arm implementation, we should never arrive 14972 * here with a zero breakFlag because we always refresh rIBASE on 14973 * return. 14974 */ 14975 EXPORT_PC 14976 movl rSELF, %eax 14977 movl rPC, OUT_ARG0(%esp) 14978 cmpb $0,offThread_breakFlags(%eax) # anything to do? 14979 movl rFP, OUT_ARG1(%esp) 14980 je 1f # reload rIBASE & resume if not 14981 movl %eax, OUT_ARG2(%esp) 14982 call dvmCheckBefore # (dPC, dFP, self) 14983 movl rSELF, %eax 149841: 14985 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 14986 jmp *dvmAsmInstructionStart+(253*4) 14987 14988/* ------------------------------ */ 14989.L_ALT_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 14990/* File: x86/alt_stub.S */ 14991/* 14992 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14993 * any interesting requests and then jump to the real instruction 14994 * handler. Unlike the Arm handler, we can't do this as a tail call 14995 * because rIBASE is caller save and we need to reload it. 14996 * 14997 * Note that unlike in the Arm implementation, we should never arrive 14998 * here with a zero breakFlag because we always refresh rIBASE on 14999 * return. 15000 */ 15001 EXPORT_PC 15002 movl rSELF, %eax 15003 movl rPC, OUT_ARG0(%esp) 15004 cmpb $0,offThread_breakFlags(%eax) # anything to do? 15005 movl rFP, OUT_ARG1(%esp) 15006 je 1f # reload rIBASE & resume if not 15007 movl %eax, OUT_ARG2(%esp) 15008 call dvmCheckBefore # (dPC, dFP, self) 15009 movl rSELF, %eax 150101: 15011 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 15012 jmp *dvmAsmInstructionStart+(254*4) 15013 15014/* ------------------------------ */ 15015.L_ALT_OP_UNUSED_FF: /* 0xff */ 15016/* File: x86/alt_stub.S */ 15017/* 15018 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15019 * any interesting requests and then jump to the real instruction 15020 * handler. Unlike the Arm handler, we can't do this as a tail call 15021 * because rIBASE is caller save and we need to reload it. 15022 * 15023 * Note that unlike in the Arm implementation, we should never arrive 15024 * here with a zero breakFlag because we always refresh rIBASE on 15025 * return. 15026 */ 15027 EXPORT_PC 15028 movl rSELF, %eax 15029 movl rPC, OUT_ARG0(%esp) 15030 cmpb $0,offThread_breakFlags(%eax) # anything to do? 15031 movl rFP, OUT_ARG1(%esp) 15032 je 1f # reload rIBASE & resume if not 15033 movl %eax, OUT_ARG2(%esp) 15034 call dvmCheckBefore # (dPC, dFP, self) 15035 movl rSELF, %eax 150361: 15037 movl offThread_curHandlerTable(%eax), rIBASE # reload rIBASE 15038 jmp *dvmAsmInstructionStart+(255*4) 15039 15040 .size dvmAsmAltInstructionStartCode, .-dvmAsmAltInstructionStartCode 15041 .global dvmAsmAltInstructionEndCode 15042dvmAsmAltInstructionEndCode: 15043 15044 .global dvmAsmInstructionStart 15045 .text 15046dvmAsmInstructionStart: 15047 .long .L_OP_NOP /* 0x00 */ 15048 .long .L_OP_MOVE /* 0x01 */ 15049 .long .L_OP_MOVE_FROM16 /* 0x02 */ 15050 .long .L_OP_MOVE_16 /* 0x03 */ 15051 .long .L_OP_MOVE_WIDE /* 0x04 */ 15052 .long .L_OP_MOVE_WIDE_FROM16 /* 0x05 */ 15053 .long .L_OP_MOVE_WIDE_16 /* 0x06 */ 15054 .long .L_OP_MOVE_OBJECT /* 0x07 */ 15055 .long .L_OP_MOVE_OBJECT_FROM16 /* 0x08 */ 15056 .long .L_OP_MOVE_OBJECT_16 /* 0x09 */ 15057 .long .L_OP_MOVE_RESULT /* 0x0a */ 15058 .long .L_OP_MOVE_RESULT_WIDE /* 0x0b */ 15059 .long .L_OP_MOVE_RESULT_OBJECT /* 0x0c */ 15060 .long .L_OP_MOVE_EXCEPTION /* 0x0d */ 15061 .long .L_OP_RETURN_VOID /* 0x0e */ 15062 .long .L_OP_RETURN /* 0x0f */ 15063 .long .L_OP_RETURN_WIDE /* 0x10 */ 15064 .long .L_OP_RETURN_OBJECT /* 0x11 */ 15065 .long .L_OP_CONST_4 /* 0x12 */ 15066 .long .L_OP_CONST_16 /* 0x13 */ 15067 .long .L_OP_CONST /* 0x14 */ 15068 .long .L_OP_CONST_HIGH16 /* 0x15 */ 15069 .long .L_OP_CONST_WIDE_16 /* 0x16 */ 15070 .long .L_OP_CONST_WIDE_32 /* 0x17 */ 15071 .long .L_OP_CONST_WIDE /* 0x18 */ 15072 .long .L_OP_CONST_WIDE_HIGH16 /* 0x19 */ 15073 .long .L_OP_CONST_STRING /* 0x1a */ 15074 .long .L_OP_CONST_STRING_JUMBO /* 0x1b */ 15075 .long .L_OP_CONST_CLASS /* 0x1c */ 15076 .long .L_OP_MONITOR_ENTER /* 0x1d */ 15077 .long .L_OP_MONITOR_EXIT /* 0x1e */ 15078 .long .L_OP_CHECK_CAST /* 0x1f */ 15079 .long .L_OP_INSTANCE_OF /* 0x20 */ 15080 .long .L_OP_ARRAY_LENGTH /* 0x21 */ 15081 .long .L_OP_NEW_INSTANCE /* 0x22 */ 15082 .long .L_OP_NEW_ARRAY /* 0x23 */ 15083 .long .L_OP_FILLED_NEW_ARRAY /* 0x24 */ 15084 .long .L_OP_FILLED_NEW_ARRAY_RANGE /* 0x25 */ 15085 .long .L_OP_FILL_ARRAY_DATA /* 0x26 */ 15086 .long .L_OP_THROW /* 0x27 */ 15087 .long .L_OP_GOTO /* 0x28 */ 15088 .long .L_OP_GOTO_16 /* 0x29 */ 15089 .long .L_OP_GOTO_32 /* 0x2a */ 15090 .long .L_OP_PACKED_SWITCH /* 0x2b */ 15091 .long .L_OP_SPARSE_SWITCH /* 0x2c */ 15092 .long .L_OP_CMPL_FLOAT /* 0x2d */ 15093 .long .L_OP_CMPG_FLOAT /* 0x2e */ 15094 .long .L_OP_CMPL_DOUBLE /* 0x2f */ 15095 .long .L_OP_CMPG_DOUBLE /* 0x30 */ 15096 .long .L_OP_CMP_LONG /* 0x31 */ 15097 .long .L_OP_IF_EQ /* 0x32 */ 15098 .long .L_OP_IF_NE /* 0x33 */ 15099 .long .L_OP_IF_LT /* 0x34 */ 15100 .long .L_OP_IF_GE /* 0x35 */ 15101 .long .L_OP_IF_GT /* 0x36 */ 15102 .long .L_OP_IF_LE /* 0x37 */ 15103 .long .L_OP_IF_EQZ /* 0x38 */ 15104 .long .L_OP_IF_NEZ /* 0x39 */ 15105 .long .L_OP_IF_LTZ /* 0x3a */ 15106 .long .L_OP_IF_GEZ /* 0x3b */ 15107 .long .L_OP_IF_GTZ /* 0x3c */ 15108 .long .L_OP_IF_LEZ /* 0x3d */ 15109 .long .L_OP_UNUSED_3E /* 0x3e */ 15110 .long .L_OP_UNUSED_3F /* 0x3f */ 15111 .long .L_OP_UNUSED_40 /* 0x40 */ 15112 .long .L_OP_UNUSED_41 /* 0x41 */ 15113 .long .L_OP_UNUSED_42 /* 0x42 */ 15114 .long .L_OP_UNUSED_43 /* 0x43 */ 15115 .long .L_OP_AGET /* 0x44 */ 15116 .long .L_OP_AGET_WIDE /* 0x45 */ 15117 .long .L_OP_AGET_OBJECT /* 0x46 */ 15118 .long .L_OP_AGET_BOOLEAN /* 0x47 */ 15119 .long .L_OP_AGET_BYTE /* 0x48 */ 15120 .long .L_OP_AGET_CHAR /* 0x49 */ 15121 .long .L_OP_AGET_SHORT /* 0x4a */ 15122 .long .L_OP_APUT /* 0x4b */ 15123 .long .L_OP_APUT_WIDE /* 0x4c */ 15124 .long .L_OP_APUT_OBJECT /* 0x4d */ 15125 .long .L_OP_APUT_BOOLEAN /* 0x4e */ 15126 .long .L_OP_APUT_BYTE /* 0x4f */ 15127 .long .L_OP_APUT_CHAR /* 0x50 */ 15128 .long .L_OP_APUT_SHORT /* 0x51 */ 15129 .long .L_OP_IGET /* 0x52 */ 15130 .long .L_OP_IGET_WIDE /* 0x53 */ 15131 .long .L_OP_IGET_OBJECT /* 0x54 */ 15132 .long .L_OP_IGET_BOOLEAN /* 0x55 */ 15133 .long .L_OP_IGET_BYTE /* 0x56 */ 15134 .long .L_OP_IGET_CHAR /* 0x57 */ 15135 .long .L_OP_IGET_SHORT /* 0x58 */ 15136 .long .L_OP_IPUT /* 0x59 */ 15137 .long .L_OP_IPUT_WIDE /* 0x5a */ 15138 .long .L_OP_IPUT_OBJECT /* 0x5b */ 15139 .long .L_OP_IPUT_BOOLEAN /* 0x5c */ 15140 .long .L_OP_IPUT_BYTE /* 0x5d */ 15141 .long .L_OP_IPUT_CHAR /* 0x5e */ 15142 .long .L_OP_IPUT_SHORT /* 0x5f */ 15143 .long .L_OP_SGET /* 0x60 */ 15144 .long .L_OP_SGET_WIDE /* 0x61 */ 15145 .long .L_OP_SGET_OBJECT /* 0x62 */ 15146 .long .L_OP_SGET_BOOLEAN /* 0x63 */ 15147 .long .L_OP_SGET_BYTE /* 0x64 */ 15148 .long .L_OP_SGET_CHAR /* 0x65 */ 15149 .long .L_OP_SGET_SHORT /* 0x66 */ 15150 .long .L_OP_SPUT /* 0x67 */ 15151 .long .L_OP_SPUT_WIDE /* 0x68 */ 15152 .long .L_OP_SPUT_OBJECT /* 0x69 */ 15153 .long .L_OP_SPUT_BOOLEAN /* 0x6a */ 15154 .long .L_OP_SPUT_BYTE /* 0x6b */ 15155 .long .L_OP_SPUT_CHAR /* 0x6c */ 15156 .long .L_OP_SPUT_SHORT /* 0x6d */ 15157 .long .L_OP_INVOKE_VIRTUAL /* 0x6e */ 15158 .long .L_OP_INVOKE_SUPER /* 0x6f */ 15159 .long .L_OP_INVOKE_DIRECT /* 0x70 */ 15160 .long .L_OP_INVOKE_STATIC /* 0x71 */ 15161 .long .L_OP_INVOKE_INTERFACE /* 0x72 */ 15162 .long .L_OP_UNUSED_73 /* 0x73 */ 15163 .long .L_OP_INVOKE_VIRTUAL_RANGE /* 0x74 */ 15164 .long .L_OP_INVOKE_SUPER_RANGE /* 0x75 */ 15165 .long .L_OP_INVOKE_DIRECT_RANGE /* 0x76 */ 15166 .long .L_OP_INVOKE_STATIC_RANGE /* 0x77 */ 15167 .long .L_OP_INVOKE_INTERFACE_RANGE /* 0x78 */ 15168 .long .L_OP_UNUSED_79 /* 0x79 */ 15169 .long .L_OP_UNUSED_7A /* 0x7a */ 15170 .long .L_OP_NEG_INT /* 0x7b */ 15171 .long .L_OP_NOT_INT /* 0x7c */ 15172 .long .L_OP_NEG_LONG /* 0x7d */ 15173 .long .L_OP_NOT_LONG /* 0x7e */ 15174 .long .L_OP_NEG_FLOAT /* 0x7f */ 15175 .long .L_OP_NEG_DOUBLE /* 0x80 */ 15176 .long .L_OP_INT_TO_LONG /* 0x81 */ 15177 .long .L_OP_INT_TO_FLOAT /* 0x82 */ 15178 .long .L_OP_INT_TO_DOUBLE /* 0x83 */ 15179 .long .L_OP_LONG_TO_INT /* 0x84 */ 15180 .long .L_OP_LONG_TO_FLOAT /* 0x85 */ 15181 .long .L_OP_LONG_TO_DOUBLE /* 0x86 */ 15182 .long .L_OP_FLOAT_TO_INT /* 0x87 */ 15183 .long .L_OP_FLOAT_TO_LONG /* 0x88 */ 15184 .long .L_OP_FLOAT_TO_DOUBLE /* 0x89 */ 15185 .long .L_OP_DOUBLE_TO_INT /* 0x8a */ 15186 .long .L_OP_DOUBLE_TO_LONG /* 0x8b */ 15187 .long .L_OP_DOUBLE_TO_FLOAT /* 0x8c */ 15188 .long .L_OP_INT_TO_BYTE /* 0x8d */ 15189 .long .L_OP_INT_TO_CHAR /* 0x8e */ 15190 .long .L_OP_INT_TO_SHORT /* 0x8f */ 15191 .long .L_OP_ADD_INT /* 0x90 */ 15192 .long .L_OP_SUB_INT /* 0x91 */ 15193 .long .L_OP_MUL_INT /* 0x92 */ 15194 .long .L_OP_DIV_INT /* 0x93 */ 15195 .long .L_OP_REM_INT /* 0x94 */ 15196 .long .L_OP_AND_INT /* 0x95 */ 15197 .long .L_OP_OR_INT /* 0x96 */ 15198 .long .L_OP_XOR_INT /* 0x97 */ 15199 .long .L_OP_SHL_INT /* 0x98 */ 15200 .long .L_OP_SHR_INT /* 0x99 */ 15201 .long .L_OP_USHR_INT /* 0x9a */ 15202 .long .L_OP_ADD_LONG /* 0x9b */ 15203 .long .L_OP_SUB_LONG /* 0x9c */ 15204 .long .L_OP_MUL_LONG /* 0x9d */ 15205 .long .L_OP_DIV_LONG /* 0x9e */ 15206 .long .L_OP_REM_LONG /* 0x9f */ 15207 .long .L_OP_AND_LONG /* 0xa0 */ 15208 .long .L_OP_OR_LONG /* 0xa1 */ 15209 .long .L_OP_XOR_LONG /* 0xa2 */ 15210 .long .L_OP_SHL_LONG /* 0xa3 */ 15211 .long .L_OP_SHR_LONG /* 0xa4 */ 15212 .long .L_OP_USHR_LONG /* 0xa5 */ 15213 .long .L_OP_ADD_FLOAT /* 0xa6 */ 15214 .long .L_OP_SUB_FLOAT /* 0xa7 */ 15215 .long .L_OP_MUL_FLOAT /* 0xa8 */ 15216 .long .L_OP_DIV_FLOAT /* 0xa9 */ 15217 .long .L_OP_REM_FLOAT /* 0xaa */ 15218 .long .L_OP_ADD_DOUBLE /* 0xab */ 15219 .long .L_OP_SUB_DOUBLE /* 0xac */ 15220 .long .L_OP_MUL_DOUBLE /* 0xad */ 15221 .long .L_OP_DIV_DOUBLE /* 0xae */ 15222 .long .L_OP_REM_DOUBLE /* 0xaf */ 15223 .long .L_OP_ADD_INT_2ADDR /* 0xb0 */ 15224 .long .L_OP_SUB_INT_2ADDR /* 0xb1 */ 15225 .long .L_OP_MUL_INT_2ADDR /* 0xb2 */ 15226 .long .L_OP_DIV_INT_2ADDR /* 0xb3 */ 15227 .long .L_OP_REM_INT_2ADDR /* 0xb4 */ 15228 .long .L_OP_AND_INT_2ADDR /* 0xb5 */ 15229 .long .L_OP_OR_INT_2ADDR /* 0xb6 */ 15230 .long .L_OP_XOR_INT_2ADDR /* 0xb7 */ 15231 .long .L_OP_SHL_INT_2ADDR /* 0xb8 */ 15232 .long .L_OP_SHR_INT_2ADDR /* 0xb9 */ 15233 .long .L_OP_USHR_INT_2ADDR /* 0xba */ 15234 .long .L_OP_ADD_LONG_2ADDR /* 0xbb */ 15235 .long .L_OP_SUB_LONG_2ADDR /* 0xbc */ 15236 .long .L_OP_MUL_LONG_2ADDR /* 0xbd */ 15237 .long .L_OP_DIV_LONG_2ADDR /* 0xbe */ 15238 .long .L_OP_REM_LONG_2ADDR /* 0xbf */ 15239 .long .L_OP_AND_LONG_2ADDR /* 0xc0 */ 15240 .long .L_OP_OR_LONG_2ADDR /* 0xc1 */ 15241 .long .L_OP_XOR_LONG_2ADDR /* 0xc2 */ 15242 .long .L_OP_SHL_LONG_2ADDR /* 0xc3 */ 15243 .long .L_OP_SHR_LONG_2ADDR /* 0xc4 */ 15244 .long .L_OP_USHR_LONG_2ADDR /* 0xc5 */ 15245 .long .L_OP_ADD_FLOAT_2ADDR /* 0xc6 */ 15246 .long .L_OP_SUB_FLOAT_2ADDR /* 0xc7 */ 15247 .long .L_OP_MUL_FLOAT_2ADDR /* 0xc8 */ 15248 .long .L_OP_DIV_FLOAT_2ADDR /* 0xc9 */ 15249 .long .L_OP_REM_FLOAT_2ADDR /* 0xca */ 15250 .long .L_OP_ADD_DOUBLE_2ADDR /* 0xcb */ 15251 .long .L_OP_SUB_DOUBLE_2ADDR /* 0xcc */ 15252 .long .L_OP_MUL_DOUBLE_2ADDR /* 0xcd */ 15253 .long .L_OP_DIV_DOUBLE_2ADDR /* 0xce */ 15254 .long .L_OP_REM_DOUBLE_2ADDR /* 0xcf */ 15255 .long .L_OP_ADD_INT_LIT16 /* 0xd0 */ 15256 .long .L_OP_RSUB_INT /* 0xd1 */ 15257 .long .L_OP_MUL_INT_LIT16 /* 0xd2 */ 15258 .long .L_OP_DIV_INT_LIT16 /* 0xd3 */ 15259 .long .L_OP_REM_INT_LIT16 /* 0xd4 */ 15260 .long .L_OP_AND_INT_LIT16 /* 0xd5 */ 15261 .long .L_OP_OR_INT_LIT16 /* 0xd6 */ 15262 .long .L_OP_XOR_INT_LIT16 /* 0xd7 */ 15263 .long .L_OP_ADD_INT_LIT8 /* 0xd8 */ 15264 .long .L_OP_RSUB_INT_LIT8 /* 0xd9 */ 15265 .long .L_OP_MUL_INT_LIT8 /* 0xda */ 15266 .long .L_OP_DIV_INT_LIT8 /* 0xdb */ 15267 .long .L_OP_REM_INT_LIT8 /* 0xdc */ 15268 .long .L_OP_AND_INT_LIT8 /* 0xdd */ 15269 .long .L_OP_OR_INT_LIT8 /* 0xde */ 15270 .long .L_OP_XOR_INT_LIT8 /* 0xdf */ 15271 .long .L_OP_SHL_INT_LIT8 /* 0xe0 */ 15272 .long .L_OP_SHR_INT_LIT8 /* 0xe1 */ 15273 .long .L_OP_USHR_INT_LIT8 /* 0xe2 */ 15274 .long .L_OP_IGET_VOLATILE /* 0xe3 */ 15275 .long .L_OP_IPUT_VOLATILE /* 0xe4 */ 15276 .long .L_OP_SGET_VOLATILE /* 0xe5 */ 15277 .long .L_OP_SPUT_VOLATILE /* 0xe6 */ 15278 .long .L_OP_IGET_OBJECT_VOLATILE /* 0xe7 */ 15279 .long .L_OP_IGET_WIDE_VOLATILE /* 0xe8 */ 15280 .long .L_OP_IPUT_WIDE_VOLATILE /* 0xe9 */ 15281 .long .L_OP_SGET_WIDE_VOLATILE /* 0xea */ 15282 .long .L_OP_SPUT_WIDE_VOLATILE /* 0xeb */ 15283 .long .L_OP_BREAKPOINT /* 0xec */ 15284 .long .L_OP_THROW_VERIFICATION_ERROR /* 0xed */ 15285 .long .L_OP_EXECUTE_INLINE /* 0xee */ 15286 .long .L_OP_EXECUTE_INLINE_RANGE /* 0xef */ 15287 .long .L_OP_INVOKE_OBJECT_INIT_RANGE /* 0xf0 */ 15288 .long .L_OP_RETURN_VOID_BARRIER /* 0xf1 */ 15289 .long .L_OP_IGET_QUICK /* 0xf2 */ 15290 .long .L_OP_IGET_WIDE_QUICK /* 0xf3 */ 15291 .long .L_OP_IGET_OBJECT_QUICK /* 0xf4 */ 15292 .long .L_OP_IPUT_QUICK /* 0xf5 */ 15293 .long .L_OP_IPUT_WIDE_QUICK /* 0xf6 */ 15294 .long .L_OP_IPUT_OBJECT_QUICK /* 0xf7 */ 15295 .long .L_OP_INVOKE_VIRTUAL_QUICK /* 0xf8 */ 15296 .long .L_OP_INVOKE_VIRTUAL_QUICK_RANGE /* 0xf9 */ 15297 .long .L_OP_INVOKE_SUPER_QUICK /* 0xfa */ 15298 .long .L_OP_INVOKE_SUPER_QUICK_RANGE /* 0xfb */ 15299 .long .L_OP_IPUT_OBJECT_VOLATILE /* 0xfc */ 15300 .long .L_OP_SGET_OBJECT_VOLATILE /* 0xfd */ 15301 .long .L_OP_SPUT_OBJECT_VOLATILE /* 0xfe */ 15302 .long .L_OP_UNUSED_FF /* 0xff */ 15303 15304 .global dvmAsmAltInstructionStart 15305 .text 15306dvmAsmAltInstructionStart: 15307 .long .L_ALT_OP_NOP /* 0x00 */ 15308 .long .L_ALT_OP_MOVE /* 0x01 */ 15309 .long .L_ALT_OP_MOVE_FROM16 /* 0x02 */ 15310 .long .L_ALT_OP_MOVE_16 /* 0x03 */ 15311 .long .L_ALT_OP_MOVE_WIDE /* 0x04 */ 15312 .long .L_ALT_OP_MOVE_WIDE_FROM16 /* 0x05 */ 15313 .long .L_ALT_OP_MOVE_WIDE_16 /* 0x06 */ 15314 .long .L_ALT_OP_MOVE_OBJECT /* 0x07 */ 15315 .long .L_ALT_OP_MOVE_OBJECT_FROM16 /* 0x08 */ 15316 .long .L_ALT_OP_MOVE_OBJECT_16 /* 0x09 */ 15317 .long .L_ALT_OP_MOVE_RESULT /* 0x0a */ 15318 .long .L_ALT_OP_MOVE_RESULT_WIDE /* 0x0b */ 15319 .long .L_ALT_OP_MOVE_RESULT_OBJECT /* 0x0c */ 15320 .long .L_ALT_OP_MOVE_EXCEPTION /* 0x0d */ 15321 .long .L_ALT_OP_RETURN_VOID /* 0x0e */ 15322 .long .L_ALT_OP_RETURN /* 0x0f */ 15323 .long .L_ALT_OP_RETURN_WIDE /* 0x10 */ 15324 .long .L_ALT_OP_RETURN_OBJECT /* 0x11 */ 15325 .long .L_ALT_OP_CONST_4 /* 0x12 */ 15326 .long .L_ALT_OP_CONST_16 /* 0x13 */ 15327 .long .L_ALT_OP_CONST /* 0x14 */ 15328 .long .L_ALT_OP_CONST_HIGH16 /* 0x15 */ 15329 .long .L_ALT_OP_CONST_WIDE_16 /* 0x16 */ 15330 .long .L_ALT_OP_CONST_WIDE_32 /* 0x17 */ 15331 .long .L_ALT_OP_CONST_WIDE /* 0x18 */ 15332 .long .L_ALT_OP_CONST_WIDE_HIGH16 /* 0x19 */ 15333 .long .L_ALT_OP_CONST_STRING /* 0x1a */ 15334 .long .L_ALT_OP_CONST_STRING_JUMBO /* 0x1b */ 15335 .long .L_ALT_OP_CONST_CLASS /* 0x1c */ 15336 .long .L_ALT_OP_MONITOR_ENTER /* 0x1d */ 15337 .long .L_ALT_OP_MONITOR_EXIT /* 0x1e */ 15338 .long .L_ALT_OP_CHECK_CAST /* 0x1f */ 15339 .long .L_ALT_OP_INSTANCE_OF /* 0x20 */ 15340 .long .L_ALT_OP_ARRAY_LENGTH /* 0x21 */ 15341 .long .L_ALT_OP_NEW_INSTANCE /* 0x22 */ 15342 .long .L_ALT_OP_NEW_ARRAY /* 0x23 */ 15343 .long .L_ALT_OP_FILLED_NEW_ARRAY /* 0x24 */ 15344 .long .L_ALT_OP_FILLED_NEW_ARRAY_RANGE /* 0x25 */ 15345 .long .L_ALT_OP_FILL_ARRAY_DATA /* 0x26 */ 15346 .long .L_ALT_OP_THROW /* 0x27 */ 15347 .long .L_ALT_OP_GOTO /* 0x28 */ 15348 .long .L_ALT_OP_GOTO_16 /* 0x29 */ 15349 .long .L_ALT_OP_GOTO_32 /* 0x2a */ 15350 .long .L_ALT_OP_PACKED_SWITCH /* 0x2b */ 15351 .long .L_ALT_OP_SPARSE_SWITCH /* 0x2c */ 15352 .long .L_ALT_OP_CMPL_FLOAT /* 0x2d */ 15353 .long .L_ALT_OP_CMPG_FLOAT /* 0x2e */ 15354 .long .L_ALT_OP_CMPL_DOUBLE /* 0x2f */ 15355 .long .L_ALT_OP_CMPG_DOUBLE /* 0x30 */ 15356 .long .L_ALT_OP_CMP_LONG /* 0x31 */ 15357 .long .L_ALT_OP_IF_EQ /* 0x32 */ 15358 .long .L_ALT_OP_IF_NE /* 0x33 */ 15359 .long .L_ALT_OP_IF_LT /* 0x34 */ 15360 .long .L_ALT_OP_IF_GE /* 0x35 */ 15361 .long .L_ALT_OP_IF_GT /* 0x36 */ 15362 .long .L_ALT_OP_IF_LE /* 0x37 */ 15363 .long .L_ALT_OP_IF_EQZ /* 0x38 */ 15364 .long .L_ALT_OP_IF_NEZ /* 0x39 */ 15365 .long .L_ALT_OP_IF_LTZ /* 0x3a */ 15366 .long .L_ALT_OP_IF_GEZ /* 0x3b */ 15367 .long .L_ALT_OP_IF_GTZ /* 0x3c */ 15368 .long .L_ALT_OP_IF_LEZ /* 0x3d */ 15369 .long .L_ALT_OP_UNUSED_3E /* 0x3e */ 15370 .long .L_ALT_OP_UNUSED_3F /* 0x3f */ 15371 .long .L_ALT_OP_UNUSED_40 /* 0x40 */ 15372 .long .L_ALT_OP_UNUSED_41 /* 0x41 */ 15373 .long .L_ALT_OP_UNUSED_42 /* 0x42 */ 15374 .long .L_ALT_OP_UNUSED_43 /* 0x43 */ 15375 .long .L_ALT_OP_AGET /* 0x44 */ 15376 .long .L_ALT_OP_AGET_WIDE /* 0x45 */ 15377 .long .L_ALT_OP_AGET_OBJECT /* 0x46 */ 15378 .long .L_ALT_OP_AGET_BOOLEAN /* 0x47 */ 15379 .long .L_ALT_OP_AGET_BYTE /* 0x48 */ 15380 .long .L_ALT_OP_AGET_CHAR /* 0x49 */ 15381 .long .L_ALT_OP_AGET_SHORT /* 0x4a */ 15382 .long .L_ALT_OP_APUT /* 0x4b */ 15383 .long .L_ALT_OP_APUT_WIDE /* 0x4c */ 15384 .long .L_ALT_OP_APUT_OBJECT /* 0x4d */ 15385 .long .L_ALT_OP_APUT_BOOLEAN /* 0x4e */ 15386 .long .L_ALT_OP_APUT_BYTE /* 0x4f */ 15387 .long .L_ALT_OP_APUT_CHAR /* 0x50 */ 15388 .long .L_ALT_OP_APUT_SHORT /* 0x51 */ 15389 .long .L_ALT_OP_IGET /* 0x52 */ 15390 .long .L_ALT_OP_IGET_WIDE /* 0x53 */ 15391 .long .L_ALT_OP_IGET_OBJECT /* 0x54 */ 15392 .long .L_ALT_OP_IGET_BOOLEAN /* 0x55 */ 15393 .long .L_ALT_OP_IGET_BYTE /* 0x56 */ 15394 .long .L_ALT_OP_IGET_CHAR /* 0x57 */ 15395 .long .L_ALT_OP_IGET_SHORT /* 0x58 */ 15396 .long .L_ALT_OP_IPUT /* 0x59 */ 15397 .long .L_ALT_OP_IPUT_WIDE /* 0x5a */ 15398 .long .L_ALT_OP_IPUT_OBJECT /* 0x5b */ 15399 .long .L_ALT_OP_IPUT_BOOLEAN /* 0x5c */ 15400 .long .L_ALT_OP_IPUT_BYTE /* 0x5d */ 15401 .long .L_ALT_OP_IPUT_CHAR /* 0x5e */ 15402 .long .L_ALT_OP_IPUT_SHORT /* 0x5f */ 15403 .long .L_ALT_OP_SGET /* 0x60 */ 15404 .long .L_ALT_OP_SGET_WIDE /* 0x61 */ 15405 .long .L_ALT_OP_SGET_OBJECT /* 0x62 */ 15406 .long .L_ALT_OP_SGET_BOOLEAN /* 0x63 */ 15407 .long .L_ALT_OP_SGET_BYTE /* 0x64 */ 15408 .long .L_ALT_OP_SGET_CHAR /* 0x65 */ 15409 .long .L_ALT_OP_SGET_SHORT /* 0x66 */ 15410 .long .L_ALT_OP_SPUT /* 0x67 */ 15411 .long .L_ALT_OP_SPUT_WIDE /* 0x68 */ 15412 .long .L_ALT_OP_SPUT_OBJECT /* 0x69 */ 15413 .long .L_ALT_OP_SPUT_BOOLEAN /* 0x6a */ 15414 .long .L_ALT_OP_SPUT_BYTE /* 0x6b */ 15415 .long .L_ALT_OP_SPUT_CHAR /* 0x6c */ 15416 .long .L_ALT_OP_SPUT_SHORT /* 0x6d */ 15417 .long .L_ALT_OP_INVOKE_VIRTUAL /* 0x6e */ 15418 .long .L_ALT_OP_INVOKE_SUPER /* 0x6f */ 15419 .long .L_ALT_OP_INVOKE_DIRECT /* 0x70 */ 15420 .long .L_ALT_OP_INVOKE_STATIC /* 0x71 */ 15421 .long .L_ALT_OP_INVOKE_INTERFACE /* 0x72 */ 15422 .long .L_ALT_OP_UNUSED_73 /* 0x73 */ 15423 .long .L_ALT_OP_INVOKE_VIRTUAL_RANGE /* 0x74 */ 15424 .long .L_ALT_OP_INVOKE_SUPER_RANGE /* 0x75 */ 15425 .long .L_ALT_OP_INVOKE_DIRECT_RANGE /* 0x76 */ 15426 .long .L_ALT_OP_INVOKE_STATIC_RANGE /* 0x77 */ 15427 .long .L_ALT_OP_INVOKE_INTERFACE_RANGE /* 0x78 */ 15428 .long .L_ALT_OP_UNUSED_79 /* 0x79 */ 15429 .long .L_ALT_OP_UNUSED_7A /* 0x7a */ 15430 .long .L_ALT_OP_NEG_INT /* 0x7b */ 15431 .long .L_ALT_OP_NOT_INT /* 0x7c */ 15432 .long .L_ALT_OP_NEG_LONG /* 0x7d */ 15433 .long .L_ALT_OP_NOT_LONG /* 0x7e */ 15434 .long .L_ALT_OP_NEG_FLOAT /* 0x7f */ 15435 .long .L_ALT_OP_NEG_DOUBLE /* 0x80 */ 15436 .long .L_ALT_OP_INT_TO_LONG /* 0x81 */ 15437 .long .L_ALT_OP_INT_TO_FLOAT /* 0x82 */ 15438 .long .L_ALT_OP_INT_TO_DOUBLE /* 0x83 */ 15439 .long .L_ALT_OP_LONG_TO_INT /* 0x84 */ 15440 .long .L_ALT_OP_LONG_TO_FLOAT /* 0x85 */ 15441 .long .L_ALT_OP_LONG_TO_DOUBLE /* 0x86 */ 15442 .long .L_ALT_OP_FLOAT_TO_INT /* 0x87 */ 15443 .long .L_ALT_OP_FLOAT_TO_LONG /* 0x88 */ 15444 .long .L_ALT_OP_FLOAT_TO_DOUBLE /* 0x89 */ 15445 .long .L_ALT_OP_DOUBLE_TO_INT /* 0x8a */ 15446 .long .L_ALT_OP_DOUBLE_TO_LONG /* 0x8b */ 15447 .long .L_ALT_OP_DOUBLE_TO_FLOAT /* 0x8c */ 15448 .long .L_ALT_OP_INT_TO_BYTE /* 0x8d */ 15449 .long .L_ALT_OP_INT_TO_CHAR /* 0x8e */ 15450 .long .L_ALT_OP_INT_TO_SHORT /* 0x8f */ 15451 .long .L_ALT_OP_ADD_INT /* 0x90 */ 15452 .long .L_ALT_OP_SUB_INT /* 0x91 */ 15453 .long .L_ALT_OP_MUL_INT /* 0x92 */ 15454 .long .L_ALT_OP_DIV_INT /* 0x93 */ 15455 .long .L_ALT_OP_REM_INT /* 0x94 */ 15456 .long .L_ALT_OP_AND_INT /* 0x95 */ 15457 .long .L_ALT_OP_OR_INT /* 0x96 */ 15458 .long .L_ALT_OP_XOR_INT /* 0x97 */ 15459 .long .L_ALT_OP_SHL_INT /* 0x98 */ 15460 .long .L_ALT_OP_SHR_INT /* 0x99 */ 15461 .long .L_ALT_OP_USHR_INT /* 0x9a */ 15462 .long .L_ALT_OP_ADD_LONG /* 0x9b */ 15463 .long .L_ALT_OP_SUB_LONG /* 0x9c */ 15464 .long .L_ALT_OP_MUL_LONG /* 0x9d */ 15465 .long .L_ALT_OP_DIV_LONG /* 0x9e */ 15466 .long .L_ALT_OP_REM_LONG /* 0x9f */ 15467 .long .L_ALT_OP_AND_LONG /* 0xa0 */ 15468 .long .L_ALT_OP_OR_LONG /* 0xa1 */ 15469 .long .L_ALT_OP_XOR_LONG /* 0xa2 */ 15470 .long .L_ALT_OP_SHL_LONG /* 0xa3 */ 15471 .long .L_ALT_OP_SHR_LONG /* 0xa4 */ 15472 .long .L_ALT_OP_USHR_LONG /* 0xa5 */ 15473 .long .L_ALT_OP_ADD_FLOAT /* 0xa6 */ 15474 .long .L_ALT_OP_SUB_FLOAT /* 0xa7 */ 15475 .long .L_ALT_OP_MUL_FLOAT /* 0xa8 */ 15476 .long .L_ALT_OP_DIV_FLOAT /* 0xa9 */ 15477 .long .L_ALT_OP_REM_FLOAT /* 0xaa */ 15478 .long .L_ALT_OP_ADD_DOUBLE /* 0xab */ 15479 .long .L_ALT_OP_SUB_DOUBLE /* 0xac */ 15480 .long .L_ALT_OP_MUL_DOUBLE /* 0xad */ 15481 .long .L_ALT_OP_DIV_DOUBLE /* 0xae */ 15482 .long .L_ALT_OP_REM_DOUBLE /* 0xaf */ 15483 .long .L_ALT_OP_ADD_INT_2ADDR /* 0xb0 */ 15484 .long .L_ALT_OP_SUB_INT_2ADDR /* 0xb1 */ 15485 .long .L_ALT_OP_MUL_INT_2ADDR /* 0xb2 */ 15486 .long .L_ALT_OP_DIV_INT_2ADDR /* 0xb3 */ 15487 .long .L_ALT_OP_REM_INT_2ADDR /* 0xb4 */ 15488 .long .L_ALT_OP_AND_INT_2ADDR /* 0xb5 */ 15489 .long .L_ALT_OP_OR_INT_2ADDR /* 0xb6 */ 15490 .long .L_ALT_OP_XOR_INT_2ADDR /* 0xb7 */ 15491 .long .L_ALT_OP_SHL_INT_2ADDR /* 0xb8 */ 15492 .long .L_ALT_OP_SHR_INT_2ADDR /* 0xb9 */ 15493 .long .L_ALT_OP_USHR_INT_2ADDR /* 0xba */ 15494 .long .L_ALT_OP_ADD_LONG_2ADDR /* 0xbb */ 15495 .long .L_ALT_OP_SUB_LONG_2ADDR /* 0xbc */ 15496 .long .L_ALT_OP_MUL_LONG_2ADDR /* 0xbd */ 15497 .long .L_ALT_OP_DIV_LONG_2ADDR /* 0xbe */ 15498 .long .L_ALT_OP_REM_LONG_2ADDR /* 0xbf */ 15499 .long .L_ALT_OP_AND_LONG_2ADDR /* 0xc0 */ 15500 .long .L_ALT_OP_OR_LONG_2ADDR /* 0xc1 */ 15501 .long .L_ALT_OP_XOR_LONG_2ADDR /* 0xc2 */ 15502 .long .L_ALT_OP_SHL_LONG_2ADDR /* 0xc3 */ 15503 .long .L_ALT_OP_SHR_LONG_2ADDR /* 0xc4 */ 15504 .long .L_ALT_OP_USHR_LONG_2ADDR /* 0xc5 */ 15505 .long .L_ALT_OP_ADD_FLOAT_2ADDR /* 0xc6 */ 15506 .long .L_ALT_OP_SUB_FLOAT_2ADDR /* 0xc7 */ 15507 .long .L_ALT_OP_MUL_FLOAT_2ADDR /* 0xc8 */ 15508 .long .L_ALT_OP_DIV_FLOAT_2ADDR /* 0xc9 */ 15509 .long .L_ALT_OP_REM_FLOAT_2ADDR /* 0xca */ 15510 .long .L_ALT_OP_ADD_DOUBLE_2ADDR /* 0xcb */ 15511 .long .L_ALT_OP_SUB_DOUBLE_2ADDR /* 0xcc */ 15512 .long .L_ALT_OP_MUL_DOUBLE_2ADDR /* 0xcd */ 15513 .long .L_ALT_OP_DIV_DOUBLE_2ADDR /* 0xce */ 15514 .long .L_ALT_OP_REM_DOUBLE_2ADDR /* 0xcf */ 15515 .long .L_ALT_OP_ADD_INT_LIT16 /* 0xd0 */ 15516 .long .L_ALT_OP_RSUB_INT /* 0xd1 */ 15517 .long .L_ALT_OP_MUL_INT_LIT16 /* 0xd2 */ 15518 .long .L_ALT_OP_DIV_INT_LIT16 /* 0xd3 */ 15519 .long .L_ALT_OP_REM_INT_LIT16 /* 0xd4 */ 15520 .long .L_ALT_OP_AND_INT_LIT16 /* 0xd5 */ 15521 .long .L_ALT_OP_OR_INT_LIT16 /* 0xd6 */ 15522 .long .L_ALT_OP_XOR_INT_LIT16 /* 0xd7 */ 15523 .long .L_ALT_OP_ADD_INT_LIT8 /* 0xd8 */ 15524 .long .L_ALT_OP_RSUB_INT_LIT8 /* 0xd9 */ 15525 .long .L_ALT_OP_MUL_INT_LIT8 /* 0xda */ 15526 .long .L_ALT_OP_DIV_INT_LIT8 /* 0xdb */ 15527 .long .L_ALT_OP_REM_INT_LIT8 /* 0xdc */ 15528 .long .L_ALT_OP_AND_INT_LIT8 /* 0xdd */ 15529 .long .L_ALT_OP_OR_INT_LIT8 /* 0xde */ 15530 .long .L_ALT_OP_XOR_INT_LIT8 /* 0xdf */ 15531 .long .L_ALT_OP_SHL_INT_LIT8 /* 0xe0 */ 15532 .long .L_ALT_OP_SHR_INT_LIT8 /* 0xe1 */ 15533 .long .L_ALT_OP_USHR_INT_LIT8 /* 0xe2 */ 15534 .long .L_ALT_OP_IGET_VOLATILE /* 0xe3 */ 15535 .long .L_ALT_OP_IPUT_VOLATILE /* 0xe4 */ 15536 .long .L_ALT_OP_SGET_VOLATILE /* 0xe5 */ 15537 .long .L_ALT_OP_SPUT_VOLATILE /* 0xe6 */ 15538 .long .L_ALT_OP_IGET_OBJECT_VOLATILE /* 0xe7 */ 15539 .long .L_ALT_OP_IGET_WIDE_VOLATILE /* 0xe8 */ 15540 .long .L_ALT_OP_IPUT_WIDE_VOLATILE /* 0xe9 */ 15541 .long .L_ALT_OP_SGET_WIDE_VOLATILE /* 0xea */ 15542 .long .L_ALT_OP_SPUT_WIDE_VOLATILE /* 0xeb */ 15543 .long .L_ALT_OP_BREAKPOINT /* 0xec */ 15544 .long .L_ALT_OP_THROW_VERIFICATION_ERROR /* 0xed */ 15545 .long .L_ALT_OP_EXECUTE_INLINE /* 0xee */ 15546 .long .L_ALT_OP_EXECUTE_INLINE_RANGE /* 0xef */ 15547 .long .L_ALT_OP_INVOKE_OBJECT_INIT_RANGE /* 0xf0 */ 15548 .long .L_ALT_OP_RETURN_VOID_BARRIER /* 0xf1 */ 15549 .long .L_ALT_OP_IGET_QUICK /* 0xf2 */ 15550 .long .L_ALT_OP_IGET_WIDE_QUICK /* 0xf3 */ 15551 .long .L_ALT_OP_IGET_OBJECT_QUICK /* 0xf4 */ 15552 .long .L_ALT_OP_IPUT_QUICK /* 0xf5 */ 15553 .long .L_ALT_OP_IPUT_WIDE_QUICK /* 0xf6 */ 15554 .long .L_ALT_OP_IPUT_OBJECT_QUICK /* 0xf7 */ 15555 .long .L_ALT_OP_INVOKE_VIRTUAL_QUICK /* 0xf8 */ 15556 .long .L_ALT_OP_INVOKE_VIRTUAL_QUICK_RANGE /* 0xf9 */ 15557 .long .L_ALT_OP_INVOKE_SUPER_QUICK /* 0xfa */ 15558 .long .L_ALT_OP_INVOKE_SUPER_QUICK_RANGE /* 0xfb */ 15559 .long .L_ALT_OP_IPUT_OBJECT_VOLATILE /* 0xfc */ 15560 .long .L_ALT_OP_SGET_OBJECT_VOLATILE /* 0xfd */ 15561 .long .L_ALT_OP_SPUT_OBJECT_VOLATILE /* 0xfe */ 15562 .long .L_ALT_OP_UNUSED_FF /* 0xff */ 15563/* File: x86/entry.S */ 15564/* 15565 * Copyright (C) 2008 The Android Open Source Project 15566 * 15567 * Licensed under the Apache License, Version 2.0 (the "License"); 15568 * you may not use this file except in compliance with the License. 15569 * You may obtain a copy of the License at 15570 * 15571 * http://www.apache.org/licenses/LICENSE-2.0 15572 * 15573 * Unless required by applicable law or agreed to in writing, software 15574 * distributed under the License is distributed on an "AS IS" BASIS, 15575 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15576 * See the License for the specific language governing permissions and 15577 * limitations under the License. 15578 */ 15579 15580 15581 .text 15582 .global dvmMterpStdRun 15583 .type dvmMterpStdRun, %function 15584/* 15585 * bool dvmMterpStdRun(Thread* self) 15586 * 15587 * Interpreter entry point. Returns changeInterp. 15588 * 15589 */ 15590dvmMterpStdRun: 15591 push %ebp # save caller base pointer 15592 movl %esp, %ebp # set our %ebp 15593 movl rSELF, %ecx # get incoming rSELF 15594/* 15595 * At this point we've allocated one slot on the stack 15596 * via push and stack is 8-byte aligned. Allocate space 15597 * for 9 spill slots, 4 local slots, 5 arg slots to bring 15598 * us to 16-byte alignment 15599 */ 15600 subl $(FRAME_SIZE-4), %esp 15601 15602/* Spill callee save regs */ 15603 movl %edi,EDI_SPILL(%ebp) 15604 movl %esi,ESI_SPILL(%ebp) 15605 movl %ebx,EBX_SPILL(%ebp) 15606 15607/* Set up "named" registers */ 15608 movl offThread_pc(%ecx),rPC 15609 movl offThread_curFrame(%ecx),rFP 15610 movl offThread_curHandlerTable(%ecx),rIBASE 15611 15612 /* Remember %esp for future "longjmp" */ 15613 movl %esp,offThread_bailPtr(%ecx) 15614 15615 /* Fetch next instruction before potential jump */ 15616 FETCH_INST 15617#if defined(WITH_JIT) 15618 GET_JIT_PROF_TABLE %ecx %eax 15619 movl $0, offThread_inJitCodeCache(%ecx) 15620 cmpl $0, %eax 15621 jne common_updateProfile # set up %ebx & %edx & rPC 15622#endif 15623 15624 /* Normal case: start executing the instruction at rPC */ 15625 GOTO_NEXT 15626 15627 .global dvmMterpStdBail 15628 .type dvmMterpStdBail, %function 15629/* 15630 * void dvmMterpStdBail(Thread* self, bool changeInterp) 15631 * 15632 * Restore the stack pointer and PC from the save point established on entry. 15633 * This is essentially the same as a longjmp, but should be cheaper. The 15634 * last instruction causes us to return to whoever called dvmMterpStdRun. 15635 * 15636 * We're not going to build a standard frame here, so the arg accesses will 15637 * look a little strange. 15638 * 15639 * On entry: 15640 * esp+4 (arg0) Thread* self 15641 * esp+8 (arg1) bool changeInterp 15642 */ 15643dvmMterpStdBail: 15644 movl 4(%esp),%ecx # grab self 15645 movl 8(%esp),%eax # changeInterp to return reg 15646 movl offThread_bailPtr(%ecx),%esp # Restore "setjmp" esp 15647 movl %esp,%ebp 15648 addl $(FRAME_SIZE-4), %ebp # Restore %ebp at point of setjmp 15649 movl EDI_SPILL(%ebp),%edi 15650 movl ESI_SPILL(%ebp),%esi 15651 movl EBX_SPILL(%ebp),%ebx 15652 movl %ebp, %esp # strip frame 15653 pop %ebp # restore caller's ebp 15654 ret # return to dvmMterpStdRun's caller 15655 15656 15657#ifdef WITH_JIT 15658 .global dvmNcgInvokeInterpreter 15659 .type dvmNcgInvokeInterpreter, %function 15660/* input: start of method in %eax */ 15661dvmNcgInvokeInterpreter: 15662 movl %eax, rPC 15663 movl rSELF, %ecx 15664 movl offThread_curHandlerTable(%ecx),rIBASE 15665 FETCH_INST_R %ecx # %edx<- opcode 15666 GOTO_NEXT_R %ecx # start executing the instruction at rPC 15667#endif 15668 15669/* 15670 * Strings 15671 */ 15672 .section .rodata 15673.LstrBadEntryPoint: 15674 .asciz "Bad entry point %d\n" 15675 15676 15677/* File: x86/footer.S */ 15678/* 15679 * Copyright (C) 2008 The Android Open Source Project 15680 * 15681 * Licensed under the Apache License, Version 2.0 (the "License"); 15682 * you may not use this file except in compliance with the License. 15683 * You may obtain a copy of the License at 15684 * 15685 * http://www.apache.org/licenses/LICENSE-2.0 15686 * 15687 * Unless required by applicable law or agreed to in writing, software 15688 * distributed under the License is distributed on an "AS IS" BASIS, 15689 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15690 * See the License for the specific language governing permissions and 15691 * limitations under the License. 15692 */ 15693/* 15694 * Common subroutines and data. 15695 */ 15696 15697#if defined(WITH_JIT) 15698/* 15699 * JIT-related re-entries into the interpreter. In general, if the 15700 * exit from a translation can at some point be chained, the entry 15701 * here requires that control arrived via a call, and that the "rp" 15702 * on TOS is actually a pointer to a 32-bit cell containing the Dalvik PC 15703 * of the next insn to handle. If no chaining will happen, the entry 15704 * should be reached via a direct jump and rPC set beforehand. 15705 */ 15706 15707 .global dvmJitToInterpPunt 15708/* 15709 * The compiler will generate a jump to this entry point when it is 15710 * having difficulty translating a Dalvik instruction. We must skip 15711 * the code cache lookup & prevent chaining to avoid bouncing between 15712 * the interpreter and code cache. rPC must be set on entry. 15713 */ 15714dvmJitToInterpPunt: 15715 GET_PC 15716#if defined(WITH_JIT_TUNING) 15717 movl rPC, OUT_ARG0(%esp) 15718 call dvmBumpPunt 15719#endif 15720 movl rSELF, %ecx 15721 movl offThread_curHandlerTable(%ecx),rIBASE 15722 movl $0, offThread_inJitCodeCache(%ecx) 15723 FETCH_INST_R %ecx 15724 GOTO_NEXT_R %ecx 15725 15726 .global dvmJitToInterpSingleStep 15727/* 15728 * Return to the interpreter to handle a single instruction. 15729 * Should be reached via a call. 15730 * On entry: 15731 * 0(%esp) <= native return address within trace 15732 * rPC <= Dalvik PC of this instruction 15733 * OUT_ARG0+4(%esp) <= Dalvik PC of next instruction 15734 */ 15735dvmJitToInterpSingleStep: 15736/* TODO */ 15737 call dvmAbort 15738#if 0 15739 pop %eax 15740 movl rSELF, %ecx 15741 movl OUT_ARG0(%esp), %edx 15742 movl %eax,offThread_jitResumeNPC(%ecx) 15743 movl %edx,offThread_jitResumeDPC(%ecx) 15744 movl $kInterpEntryInstr,offThread_entryPoint(%ecx) 15745 movl $1,rINST # changeInterp <= true 15746 jmp common_gotoBail 15747#endif 15748 15749 .global dvmJitToInterpNoChainNoProfile 15750/* 15751 * Return from the translation cache to the interpreter to do method 15752 * invocation. Check if the translation exists for the callee, but don't 15753 * chain to it. rPC must be set on entry. 15754 */ 15755dvmJitToInterpNoChainNoProfile: 15756#if defined(WITH_JIT_TUNING) 15757 SPILL_TMP1(%eax) 15758 call dvmBumpNoChain 15759 UNSPILL_TMP1(%eax) 15760#endif 15761 movl %eax, rPC 15762 movl rSELF, %eax 15763 movl rPC,OUT_ARG0(%esp) 15764 movl %eax,OUT_ARG1(%esp) 15765 call dvmJitGetTraceAddrThread # (pc, self) 15766 movl rSELF,%ecx # ecx <- self 15767 movl %eax,offThread_inJitCodeCache(%ecx) # set inJitCodeCache flag 15768 cmpl $0, %eax 15769 jz 1f 15770 jmp *%eax # exec translation if we've got one 15771 # won't return 157721: 15773 EXPORT_PC 15774 movl rSELF, %ecx 15775 movl offThread_curHandlerTable(%ecx),rIBASE 15776 FETCH_INST_R %ecx 15777 GOTO_NEXT_R %ecx 15778 15779/* 15780 * Return from the translation cache and immediately request a 15781 * translation from the exit target, but don't attempt to chain. 15782 * rPC set on entry. 15783 */ 15784 .global dvmJitToInterpTraceSelectNoChain 15785dvmJitToInterpTraceSelectNoChain: 15786#if defined(WITH_JIT_TUNING) 15787 movl %edx, OUT_ARG0(%esp) 15788 call dvmBumpNoChain 15789#endif 15790 movl %ebx, rPC 15791 lea 4(%esp), %esp #to recover the esp update due to function call 15792 movl rSELF, %eax 15793 movl rPC,OUT_ARG0(%esp) 15794 movl %eax,OUT_ARG1(%esp) 15795 call dvmJitGetTraceAddrThread # (pc, self) 15796 movl rSELF,%ecx 15797 cmpl $0,%eax 15798 movl %eax,offThread_inJitCodeCache(%ecx) # set inJitCodeCache flag 15799 jz 1f 15800 jmp *%eax # jump to tranlation 15801 # won't return 15802 15803/* No Translation - request one */ 158041: 15805 GET_JIT_PROF_TABLE %ecx %eax 15806 cmpl $0, %eax # JIT enabled? 15807 jnz 2f # Request one if so 15808 movl rSELF, %ecx 15809 movl offThread_curHandlerTable(%ecx),rIBASE 15810 FETCH_INST_R %ecx # Continue interpreting if not 15811 GOTO_NEXT_R %ecx 158122: 15813 ## Looks like an EXPORT_PC is needed here. Now jmp to common_selectTrace2 15814 movl $kJitTSelectRequestHot,%eax # ask for trace select 15815 jmp common_selectTrace 15816 15817/* 15818 * Return from the translation cache and immediately request a 15819 * translation for the exit target. Reached via a call, and 15820 * (TOS)->rPC. 15821 */ 15822 .global dvmJitToInterpTraceSelect 15823dvmJitToInterpTraceSelect: 15824 movl 0(%esp), %eax # get return address 15825 movl %ebx, rPC # get first argument (target rPC) 15826 15827 ## TODO, need to clean up stack manipulation ... this isn't signal safe and 15828 ## doesn't use the calling conventions of header.S 15829 lea 4(%esp), %esp #to recover the esp update due to function call 15830 15831 ## An additional 5B instruction "jump 0" was added for a thread-safe 15832 ## chaining cell update in JIT code cache. So the offset is now -17=-12-5. 15833 lea -17(%eax), %ebx #$JIT_OFFSET_CHAIN_START(%eax), %ebx 15834 lea -4(%esp), %esp 15835 movl rSELF, %eax 15836 movl rPC,OUT_ARG0(%esp) 15837 movl %eax,OUT_ARG1(%esp) 15838 call dvmJitGetTraceAddrThread # (pc, self) 15839 lea 4(%esp), %esp 15840 cmpl $0,%eax 15841 movl rSELF, %ecx 15842 movl %eax,offThread_inJitCodeCache(%ecx) # set inJitCodeCache flag 15843 jz 1b # no - ask for one 15844 movl %eax,OUT_ARG0(%esp) 15845 movl rINST,OUT_ARG1(%esp) 15846 call dvmJitChain # Attempt dvmJitChain(codeAddr,chainAddr) 15847 cmpl $0,%eax # Success? 15848 jz toInterpreter # didn't chain - interpret 15849 jmp *%eax 15850 # won't return 15851 15852/* 15853 * Placeholder entries for x86 JIT 15854 */ 15855 .global dvmJitToInterpBackwardBranch 15856dvmJitToInterpBackwardBranch: 15857 15858 .global dvmJitToExceptionThrown 15859dvmJitToExceptionThrown: //rPC in 15860 movl rSELF, %edx 15861 GET_PC 15862 movl $0, offThread_inJitCodeCache(%edx) 15863 jmp common_exceptionThrown 15864 15865 .global dvmJitToInterpNormal 15866dvmJitToInterpNormal: 15867/* one input: the target rPC value */ 15868 movl 0(%esp), %eax # get return address 15869 movl %ebx, rPC # get first argument (target rPC) 15870 15871 ## TODO, need to clean up stack manipulation ... this isn't signal safe and 15872 ## doesn't use the calling conventions of header.S 15873 15874 ## An additional 5B instruction "jump 0" was added for a thread-safe 15875 ## chaining cell update in JIT code cache. So the offset is now -17=-12-5. 15876 lea -17(%eax), %ebx #$JIT_OFFSET_CHAIN_START(%eax), %ebx 15877 lea 4(%esp), %esp 15878 movl rPC, OUT_ARG0(%esp) 15879 movl rSELF, %ecx 15880 movl %ecx, OUT_ARG1(%esp) 15881 call dvmJitGetTraceAddrThread 15882 ## Here is the change from using rGLUE to rSELF for accessing the 15883 ## JIT code cache flag 15884 movl rSELF, %ecx 15885 movl %eax, offThread_inJitCodeCache(%ecx) # set inJitCodeCache flag 15886 #lea 4(%esp), %esp 15887 cmp $0, %eax 15888 je toInterpreter 15889 #lea -8(%esp), %esp 15890 movl %ebx, OUT_ARG1(%esp) # %ebx live thorugh dvmJitGetTraceAddrThread 15891 movl %eax, OUT_ARG0(%esp) # first argument 15892 call dvmJitChain 15893 #lea 8(%esp), %esp 15894 cmp $0, %eax 15895 je toInterpreter 15896 jmp *%eax #to native address 15897 15898 .global dvmJitToInterpNoChain 15899dvmJitToInterpNoChain: 15900dvmJitToInterpNoChain: #rPC in eax 15901#if defined(WITH_JIT_TUNING) 15902 SPILL_TMP1(%eax) 15903 call dvmBumpNoChain 15904 UNSPILL_TMP1(%eax) 15905#endif 15906 ## TODO, need to clean up stack manipulation ... this isn't signal safe and 15907 ## doesn't use the calling conventions of header.S 15908 movl %eax, rPC 15909 movl rPC, OUT_ARG0(%esp) 15910 movl rSELF, %ecx 15911 movl %ecx, OUT_ARG1(%esp) 15912 call dvmJitGetTraceAddrThread 15913 ## Here is the change from using rGLUE to rSELF for accessing the 15914 ## JIT code cache flag 15915 movl rSELF, %ecx 15916 movl %eax, offThread_inJitCodeCache(%ecx) # set inJitCodeCache flag 15917 cmp $0, %eax 15918 je toInterpreter 15919 jmp *%eax #to native address 15920 15921toInterpreter: 15922 EXPORT_PC 15923 movl rSELF, %ecx 15924 movl offThread_curHandlerTable(%ecx), rIBASE 15925 FETCH_INST 15926 movl offThread_pJitProfTable(%ecx), %eax 15927 #Fallthrough 15928 15929/* ebx holds the pointer to the jit profile table 15930 edx has the opCode */ 15931common_testUpdateProfile: 15932 cmp $0, %eax 15933 je 4f 15934/* eax holds the pointer to the jit profile table 15935 edx has the opCode 15936 rPC points to the next bytecode */ 15937 15938common_updateProfile: 15939 # quick & dirty hash 15940 movl rPC, %ecx 15941 shrl $12, %ecx 15942 xorl rPC, %ecx 15943 andl $((1<<JIT_PROF_SIZE_LOG_2)-1), %ecx 15944 decb (%ecx,%eax) 15945 #jmp 1f # remove 15946 jz 2f 159471: 15948 GOTO_NEXT 159492: 15950common_Profile: 15951/* 15952 * Here, we switch to the debug interpreter to request 15953 * trace selection. First, though, check to see if there 15954 * is already a native translation in place (and, if so, 15955 * jump to it now. 15956 */ 15957 SPILL(rIBASE) 15958 SPILL_TMP1(rINST) 15959 movl rSELF, rIBASE 15960 GET_JIT_THRESHOLD rIBASE rINST # leaves rSELF in %ecx 15961 EXPORT_PC 15962 movb rINSTbl,(%ecx,%eax) # reset counter 15963 movl rIBASE,rINST # preserve rSELF 15964 movl rSELF, %eax 15965 movl rPC,OUT_ARG0(%esp) 15966 movl rIBASE,OUT_ARG1(%esp) 15967 call dvmJitGetTraceAddrThread # (pc, self) 15968 UNSPILL(rIBASE) 15969 movl %eax,offThread_inJitCodeCache(rINST) # set the inJitCodeCache flag 15970 UNSPILL_TMP1(rINST) 15971 cmpl $0,%eax 15972 #jmp 1f # remove 15973 jz 1f 15974 jmp *%eax # TODO: decide call vs/ jmp!. No return either way 159751: 15976 movl $kJitTSelectRequest,%eax 15977 # On entry, eax<- jitState, rPC valid 15978common_selectTrace: 15979 mov %ebx, EBX_SPILL(%ebp) 15980 movl rSELF, %ebx 15981 movzwl offThread_subMode(%ebx), %ecx 15982 and $(kSubModeJitTraceBuild | kSubModeJitSV), %ecx 15983 jne 3f # already doing JIT work, continue 15984 movl %eax, offThread_jitState(%ebx) 15985 movl rSELF, %eax 15986 movl %eax, OUT_ARG0(%esp) 15987 15988/* 15989 * Call out to validate trace-building request. If successful, rIBASE will be swapped 15990 * to send us into single-steppign trace building mode, so we need to refresh before 15991 * we continue. 15992 */ 15993 15994 EXPORT_PC 15995 SAVE_PC_FP_TO_SELF %ecx 15996 call dvmJitCheckTraceRequest 159973: 15998 mov EBX_SPILL(%ebp), %ebx 15999 FETCH_INST 16000 movl rSELF, %ecx 16001 movl offThread_curHandlerTable(%ecx), rIBASE 160024: 16003 GOTO_NEXT 16004 16005common_selectTrace2: 16006 mov %ebx, EBX_SPILL(%ebp) 16007 movl rSELF, %ebx 16008 movl %ebx, OUT_ARG0(%esp) 16009 movl %eax, offThread_jitState(%ebx) 16010 movzwl offThread_subMode(%ebx), %ecx 16011 mov EBX_SPILL(%ebp), %ebx 16012 and (kSubModeJitTraceBuild | kSubModeJitSV), %ecx 16013 jne 3f # already doing JIT work, continue 16014 16015 16016 16017/* 16018 * Call out to validate trace-building request. If successful, rIBASE will be swapped 16019 * to send us into single-steppign trace building mode, so we need to refresh before 16020 * we continue. 16021 */ 16022 16023 EXPORT_PC 16024 SAVE_PC_FP_TO_SELF %ecx 16025 call dvmJitCheckTraceRequest 160263: 16027 FETCH_INST 16028 movl rSELF, %ecx 16029 movl offThread_curHandlerTable(%ecx), rIBASE 160304: 16031 GOTO_NEXT 16032 16033#endif 16034 16035/* 16036 * For the invoke codes we need to know what register holds the "this" pointer. However 16037 * it seems the this pointer is assigned consistently most times it is in %ecx but other 16038 * times it is in OP_INVOKE_INTERFACE, OP_INVOKE_SUPER_QUICK, or OP_INVOKE_VIRTUAL_QUICK. 16039*/ 16040 16041/* 16042 * Common code for method invocation with range. 16043 * 16044 * On entry: 16045 * eax = Method* methodToCall 16046 * ecx = "this" 16047 * rINSTw trashed, must reload 16048 * rIBASE trashed, must reload before resuming interpreter 16049 */ 16050 16051common_invokeMethodRange: 16052.LinvokeNewRange: 16053#if defined(WITH_JIT) 16054 SPILL_TMP1(%edx) 16055 SPILL_TMP2(%ebx) 16056 movl rSELF, %edx 16057 movzwl offThread_subMode(%edx), %ebx 16058 and $kSubModeJitTraceBuild, %ebx 16059 jz 6f 16060 call save_callsiteinfo 160616: 16062 UNSPILL_TMP2(%ebx) 16063 UNSPILL_TMP1(%edx) 16064#endif 16065 /* 16066 * prepare to copy args to "outs" area of current frame 16067 */ 16068 16069 movzbl 1(rPC),rINST # rINST<- AA 16070 movzwl 4(rPC), %ecx # %ecx<- CCCC 16071 SAVEAREA_FROM_FP %edx # %edx<- &StackSaveArea 16072 test rINST, rINST 16073 movl rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- AA 16074 jz .LinvokeArgsDone # no args; jump to args done 16075 16076 16077 /* 16078 * %eax=methodToCall, %ecx=CCCC, LOCAL0_OFFSET(%ebp)=count, 16079 * %edx=&outs (&stackSaveArea). (very few methods have > 10 args; 16080 * could unroll for common cases) 16081 */ 16082 16083.LinvokeRangeArgs: 16084 movl %ebx, LOCAL1_OFFSET(%ebp) # LOCAL1_OFFSET(%ebp)<- save %ebx 16085 lea (rFP, %ecx, 4), %ecx # %ecx<- &vCCCC 16086 shll $2, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- offset 16087 subl LOCAL0_OFFSET(%ebp), %edx # %edx<- update &outs 16088 shrl $2, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- offset 160891: 16090 movl (%ecx), %ebx # %ebx<- vCCCC 16091 lea 4(%ecx), %ecx # %ecx<- &vCCCC++ 16092 subl $1, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET<- LOCAL0_OFFSET-- 16093 movl %ebx, (%edx) # *outs<- vCCCC 16094 lea 4(%edx), %edx # outs++ 16095 jne 1b # loop if count (LOCAL0_OFFSET(%ebp)) not zero 16096 movl LOCAL1_OFFSET(%ebp), %ebx # %ebx<- restore %ebx 16097 jmp .LinvokeArgsDone # continue 16098 16099 /* 16100 * %eax is "Method* methodToCall", the method we're trying to call 16101 * prepare to copy args to "outs" area of current frame 16102 * rIBASE trashed, must reload before resuming interpreter 16103 */ 16104 16105common_invokeMethodNoRange: 16106#if defined(WITH_JIT) 16107 SPILL_TMP1(%edx) 16108 SPILL_TMP2(%ebx) 16109 movl rSELF, %edx 16110 movzwl offThread_subMode(%edx), %ebx 16111 and $kSubModeJitTraceBuild, %ebx 16112 jz 6f 16113 call save_callsiteinfo 161146: 16115 UNSPILL_TMP2(%ebx) 16116 UNSPILL_TMP1(%edx) 16117#endif 16118.LinvokeNewNoRange: 16119 movzbl 1(rPC),rINST # rINST<- BA 16120 movl rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- BA 16121 shrl $4, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- B 16122 je .LinvokeArgsDone # no args; jump to args done 16123 movzwl 4(rPC), %ecx # %ecx<- GFED 16124 SAVEAREA_FROM_FP %edx # %edx<- &StackSaveArea 16125 16126 /* 16127 * %eax=methodToCall, %ecx=GFED, LOCAL0_OFFSET(%ebp)=count, %edx=outs 16128 */ 16129 16130.LinvokeNonRange: 16131 cmp $2, LOCAL0_OFFSET(%ebp) # compare LOCAL0_OFFSET(%ebp) to 2 16132 movl %ecx, LOCAL1_OFFSET(%ebp) # LOCAL1_OFFSET(%ebp)<- GFED 16133 jl 1f # handle 1 arg 16134 je 2f # handle 2 args 16135 cmp $4, LOCAL0_OFFSET(%ebp) # compare LOCAL0_OFFSET(%ebp) to 4 16136 jl 3f # handle 3 args 16137 je 4f # handle 4 args 161385: 16139 andl $15, rINST # rINSTw<- A 16140 lea -4(%edx), %edx # %edx<- update &outs; &outs-- 16141 movl (rFP, rINST, 4), %ecx # %ecx<- vA 16142 movl %ecx, (%edx) # *outs<- vA 16143 movl LOCAL1_OFFSET(%ebp), %ecx # %ecx<- GFED 161444: 16145 shr $12, %ecx # %ecx<- G 16146 lea -4(%edx), %edx # %edx<- update &outs; &outs-- 16147 movl (rFP, %ecx, 4), %ecx # %ecx<- vG 16148 movl %ecx, (%edx) # *outs<- vG 16149 movl LOCAL1_OFFSET(%ebp), %ecx # %ecx<- GFED 161503: 16151 and $0x0f00, %ecx # %ecx<- 0F00 16152 shr $8, %ecx # %ecx<- F 16153 lea -4(%edx), %edx # %edx<- update &outs; &outs-- 16154 movl (rFP, %ecx, 4), %ecx # %ecx<- vF 16155 movl %ecx, (%edx) # *outs<- vF 16156 movl LOCAL1_OFFSET(%ebp), %ecx # %ecx<- GFED 161572: 16158 and $0x00f0, %ecx # %ecx<- 00E0 16159 shr $4, %ecx # %ecx<- E 16160 lea -4(%edx), %edx # %edx<- update &outs; &outs-- 16161 movl (rFP, %ecx, 4), %ecx # %ecx<- vE 16162 movl %ecx, (%edx) # *outs<- vE 16163 movl LOCAL1_OFFSET(%ebp), %ecx # %ecx<- GFED 161641: 16165 and $0x000f, %ecx # %ecx<- 000D 16166 movl (rFP, %ecx, 4), %ecx # %ecx<- vD 16167 movl %ecx, -4(%edx) # *--outs<- vD 161680: 16169 16170 /* 16171 * %eax is "Method* methodToCall", the method we're trying to call 16172 * find space for the new stack frame, check for overflow 16173 */ 16174 16175.LinvokeArgsDone: 16176 movzwl offMethod_registersSize(%eax), %edx # %edx<- methodToCall->regsSize 16177 movzwl offMethod_outsSize(%eax), %ecx # %ecx<- methodToCall->outsSize 16178 movl %eax, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET<- methodToCall 16179 shl $2, %edx # %edx<- update offset 16180 SAVEAREA_FROM_FP %eax # %eax<- &StackSaveArea 16181 subl %edx, %eax # %eax<- newFP; (old savearea - regsSize) 16182 movl rSELF,%edx # %edx<- pthread 16183 movl %eax, LOCAL1_OFFSET(%ebp) # LOCAL1_OFFSET(%ebp)<- &outs 16184 subl $sizeofStackSaveArea, %eax # %eax<- newSaveArea (stack save area using newFP) 16185 movl offThread_interpStackEnd(%edx), %edx # %edx<- self->interpStackEnd 16186 movl %edx, TMP_SPILL1(%ebp) # spill self->interpStackEnd 16187 shl $2, %ecx # %ecx<- update offset for outsSize 16188 movl %eax, %edx # %edx<- newSaveArea 16189 sub %ecx, %eax # %eax<- bottom; (newSaveArea - outsSize) 16190 cmp TMP_SPILL1(%ebp), %eax # compare interpStackEnd and bottom 16191 movl LOCAL0_OFFSET(%ebp), %eax # %eax<- restore methodToCall 16192 jl .LstackOverflow # handle frame overflow 16193 16194 /* 16195 * set up newSaveArea 16196 */ 16197 16198#ifdef EASY_GDB 16199 SAVEAREA_FROM_FP %ecx # %ecx<- &StackSaveArea 16200 movl %ecx, offStackSaveArea_prevSave(%edx) # newSaveArea->prevSave<- &outs 16201#endif 16202 movl rSELF,%ecx # %ecx<- pthread 16203 movl rFP, offStackSaveArea_prevFrame(%edx) # newSaveArea->prevFrame<- rFP 16204 movl rPC, offStackSaveArea_savedPc(%edx) # newSaveArea->savedPc<- rPC 16205#if defined(WITH_JIT) 16206 movl $0, offStackSaveArea_returnAddr(%edx) 16207#endif 16208 16209 /* Any special actions to take? */ 16210 cmpw $0, offThread_subMode(%ecx) 16211 jne 2f # Yes - handle them 162121: 16213 testl $ACC_NATIVE, offMethod_accessFlags(%eax) # check for native call 16214 movl %eax, offStackSaveArea_method(%edx) # newSaveArea->method<- method to call 16215 jne .LinvokeNative # handle native call 16216 16217 /* 16218 * Update "self" values for the new method 16219 * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFp 16220 */ 16221 movl offMethod_clazz(%eax), %edx # %edx<- method->clazz 16222 movl offClassObject_pDvmDex(%edx), %edx # %edx<- method->clazz->pDvmDex 16223 movl %eax, offThread_method(%ecx) # self->method<- methodToCall 16224 movl %edx, offThread_methodClassDex(%ecx) # self->methodClassDex<- method->clazz->pDvmDex 16225 movl offMethod_insns(%eax), rPC # rPC<- methodToCall->insns 16226 movl $1, offThread_debugIsMethodEntry(%ecx) 16227 movl LOCAL1_OFFSET(%ebp), rFP # rFP<- newFP 16228 movl rFP, offThread_curFrame(%ecx) # curFrame<-newFP 16229 movl offThread_curHandlerTable(%ecx),rIBASE 16230 FETCH_INST 16231#if defined(WITH_JIT) 16232 /* rPC is already updated */ 16233 GET_JIT_PROF_TABLE %ecx %eax 16234 cmp $0, %eax 16235 jne common_updateProfile # set up %ebx & %edx & rPC 16236#endif 16237 GOTO_NEXT # jump to methodToCall->insns 16238 162392: 16240 /* 16241 * On entry, preserve all: 16242 * %eax: method 16243 * %ecx: self 16244 * %edx: new save area 16245 */ 16246 SPILL_TMP1(%eax) # preserve methodToCall 16247 SPILL_TMP2(%edx) # preserve newSaveArea 16248 movl rPC, offThread_pc(%ecx) # update interpSave.pc 16249 movl %ecx, OUT_ARG0(%esp) 16250 movl %eax, OUT_ARG1(%esp) 16251 call dvmReportInvoke # (self, method) 16252 UNSPILL_TMP1(%eax) 16253 UNSPILL_TMP2(%edx) 16254 movl rSELF,%ecx # restore rSELF 16255 jmp 1b 16256 16257 /* 16258 * Prep for the native call 16259 * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFP, %edx=newSaveArea, %ecx=self 16260 */ 16261 16262.LinvokeNative: 16263 movl offThread_jniLocal_topCookie(%ecx), rINST # rINST<- self->localRef->... 16264 movl rINST, offStackSaveArea_localRefCookie(%edx) # newSaveArea->localRefCookie<- top 16265 movl %edx, LOCAL2_OFFSET(%ebp) # save newSaveArea 16266 movl LOCAL1_OFFSET(%ebp), rINST # rINST<- newFP 16267 movl rINST, offThread_curFrame(%ecx) # curFrame<- newFP 16268 cmpw $0, offThread_subMode(%ecx) # Anything special going on? 16269 jne 11f # yes - handle it 16270 movl %ecx, OUT_ARG3(%esp) # push parameter self 16271 movl %eax, OUT_ARG2(%esp) # push parameter methodToCall 16272 lea offThread_retval(%ecx), %ecx # %ecx<- &retval 16273 movl %ecx, OUT_ARG1(%esp) # push parameter &retval 16274 movl rINST, OUT_ARG0(%esp) # push parameter newFP 16275 call *offMethod_nativeFunc(%eax) # call methodToCall->nativeFunc 162767: 16277 movl LOCAL2_OFFSET(%ebp), %ecx # %ecx<- newSaveArea 16278 movl rSELF, %eax # %eax<- self 16279 movl offStackSaveArea_localRefCookie(%ecx), %edx # %edx<- old top 16280 cmp $0, offThread_exception(%eax) # check for exception 16281 movl rFP, offThread_curFrame(%eax) # curFrame<- rFP 16282 movl %edx, offThread_jniLocal_topCookie(%eax) # new top <- old top 16283 jne common_exceptionThrown # handle exception 16284 movl offThread_curHandlerTable(%eax),rIBASE 16285 FETCH_INST_OPCODE 3 %ecx 16286 ADVANCE_PC 3 16287 GOTO_NEXT_R %ecx # jump to next instruction 16288 1628911: 16290 /* 16291 * Handle any special subMode actions 16292 * %eax=methodToCall, rINST=newFP, %ecx=self 16293 */ 16294 SPILL_TMP1(%eax) # save methodTocall 16295 movl rPC, offThread_pc(%ecx) 16296 movl %ecx, OUT_ARG1(%esp) 16297 movl %eax, OUT_ARG0(%esp) 16298 movl rFP, OUT_ARG2(%esp) 16299 call dvmReportPreNativeInvoke # (methodToCall, self, fp) 16300 UNSPILL_TMP1(%eax) # restore methodToCall 16301 movl rSELF,%ecx # restore self 16302 16303 /* Do the native call */ 16304 movl %ecx, OUT_ARG3(%esp) # push parameter self 16305 lea offThread_retval(%ecx), %ecx # %ecx<- &retval 16306 movl %eax, OUT_ARG2(%esp) # push parameter methodToCall 16307 movl %ecx, OUT_ARG1(%esp) # push parameter &retval 16308 movl rINST, OUT_ARG0(%esp) # push parameter newFP 16309 call *offMethod_nativeFunc(%eax) # call methodToCall->nativeFunc 16310 16311 UNSPILL_TMP1(%eax) # restore methodToCall 16312 movl rSELF, %ecx 16313 movl %ecx, OUT_ARG1(%esp) 16314 movl %eax, OUT_ARG0(%esp) 16315 movl rFP, OUT_ARG2(%esp) 16316 call dvmReportPostNativeInvoke # (methodToCall, self, fp) 16317 jmp 7b # rejoin 16318 16319.LstackOverflow: # eax=methodToCall 16320 movl %eax, OUT_ARG1(%esp) # push parameter methodToCall 16321 movl rSELF,%eax # %eax<- self 16322 movl %eax, OUT_ARG0(%esp) # push parameter self 16323 call dvmHandleStackOverflow # call: (Thread* self, Method* meth) 16324 jmp common_exceptionThrown # handle exception 16325 16326 16327/* 16328 * Common code for handling a return instruction 16329 */ 16330common_returnFromMethod: 16331 movl rSELF, %ecx 16332 SAVEAREA_FROM_FP %eax # %eax<- saveArea(old) 16333 cmpw $0, offThread_subMode(%ecx) # special action needed? 16334 jne 19f # go if so 1633514: 16336 16337 movl offStackSaveArea_prevFrame(%eax), rFP # rFP<- saveArea->PrevFrame 16338 movl (offStackSaveArea_method - sizeofStackSaveArea)(rFP), rINST # rINST<- method we are returning to 16339 cmpl $0, rINST # check for break frame 16340 je common_gotoBail # bail if break frame 16341 movl offThread_curHandlerTable(%ecx),rIBASE 16342 movl offStackSaveArea_savedPc(%eax), rPC # rPC<- saveAreaOld->savedPc 16343#if defined(WITH_JIT) 16344 movl offStackSaveArea_returnAddr(%eax), %ecx 16345#endif 16346 movl rSELF, %eax 16347 movl rINST, offThread_method(%eax) # glue->method<- newSave->method 16348 movl offMethod_clazz(rINST), rINST # rINST<- method->clazz 16349 movl rFP, offThread_curFrame(%eax) # glue->self->curFrame<- rFP 16350#if defined(WITH_JIT) 16351 //update self->offThread_inJitCodeCache 16352 movl %ecx, offThread_inJitCodeCache(%eax) 16353#endif 16354 movl offClassObject_pDvmDex(rINST), rINST # rINST<- method->clazz->pDvmDex 16355 movl rINST, offThread_methodClassDex(%eax) # glue->pDvmDex<- method->clazz->pDvmDex 16356#if defined(WITH_JIT) 16357 cmp $0, %ecx 16358 je .returnToBC 16359 movl %ecx, %eax 16360 jmp *%eax 16361#endif 16362 16363.returnToBC: 16364 16365#if defined(WITH_JIT) 16366 FETCH_INST_OPCODE 3, %ecx # %eax<- next instruction hi; fetch, advance 16367 // %ecx has the opcode 16368 addl $6, rPC # 3*2 = 6 16369 SPILL_TMP1 (%ecx) 16370 movl rSELF, %ecx 16371 FETCH_INST 16372 UNSPILL_TMP1 (%ecx) 16373 movzbl 1(rPC), rINST 16374 jmp *(rIBASE,%ecx,4) 16375#else 16376 FETCH_INST_WORD 3 16377 ADVANCE_PC 3 16378 GOTO_NEXT 16379#endif 16380 1638119: 16382 /* 16383 * Handle special subMode actions 16384 * On entry, rFP: prevFP, %ecx: self, %eax: saveArea 16385 */ 16386 SPILL_TMP1(%ebx) 16387 movl offStackSaveArea_prevFrame(%eax), %ebx # %ebx<- saveArea->PrevFrame 16388 movl rPC, offThread_pc(%ecx) # update interpSave.pc 16389 movl %ebx, offThread_curFrame(%ecx) # update interpSave.curFrame 16390 movl %ecx, OUT_ARG0(%esp) # parameter self 16391 call dvmReportReturn # (self) 16392 UNSPILL_TMP1(%ebx) 16393 movl rSELF, %ecx # restore self 16394 SAVEAREA_FROM_FP %eax # restore saveArea 16395 jmp 14b 16396 16397 16398/* 16399 * Prepare to strip the current frame and "longjump" back to caller of 16400 * dvmMterpStdRun. 16401 * 16402 * on entry: 16403 * rINST holds changeInterp 16404 * ecx holds self pointer 16405 * 16406 * expected profile: dvmMterpStdBail(Thread *self, bool changeInterp) 16407 */ 16408common_gotoBail: 16409 movl rPC,offThread_pc(%ecx) # export state to self 16410 movl rFP,offThread_curFrame(%ecx) 16411 movl %ecx,OUT_ARG0(%esp) # self in arg0 16412 movl rINST,OUT_ARG1(%esp) # changeInterp in arg1 16413 call dvmMterpStdBail # bail out.... 16414 16415/* 16416 * The JIT's invoke method needs to remember the callsite class and 16417 * target pair. Save them here so that they are available to 16418 * dvmCheckJit following the interpretation of this invoke. 16419 * 16420 * eax = Method* methodToCall 16421 * ecx = "this" 16422 * edx = rSELF 16423 * ebx = free to use 16424 */ 16425#if defined(WITH_JIT) 16426save_callsiteinfo: 16427 cmp $0, %ecx 16428 je 2f 16429 movl offObject_clazz(%ecx), %ecx 164302: 16431 movl rSELF, %ebx 16432 movl %eax, offThread_methodToCall(%ebx) 16433 movl %ecx, offThread_callsiteClass(%ebx) 16434 ret 16435#endif 16436 16437#if defined(WITH_JIT) 16438 16439 /* 16440 * If the JIT is actively building a trace we need to make sure 16441 * that the field is fully resolved before including the current 16442 * instruction. 16443 * 16444 * On entry: 16445 * %ecx: &dvmDex->pResFields[field] 16446 * %eax: field pointer (must preserve) 16447 */ 16448common_verifyField: 16449 movl %ebx, TMP_SPILL1(%ebp) 16450 movl rSELF, %ebx 16451 movzwl offThread_subMode(%ebx), %ebx 16452 andl $kSubModeJitTraceBuild, %ebx 16453 movl TMP_SPILL1(%ebp), %ebx 16454 jne 1f 16455 ret 164561: 16457 movl (%ecx), %ecx 16458 cmp $0, %ecx 16459 je 1f 16460 ret 164611: 16462 SPILL_TMP1(%eax) 16463 SPILL_TMP2(%edx) 16464 movl rSELF, %ecx 16465 # Because we call into this helper from a bytecode, we have 16466 # to be careful not to write over the return address when using 16467 # the OUT_ARG macros 16468 lea -8(%esp), %esp 16469 movl %ecx, OUT_ARG0(%esp) 16470 movl rPC, OUT_ARG1(%esp) 16471 call dvmJitEndTraceSelect 16472 lea 8(%esp), %esp 16473 UNSPILL_TMP2(%edx) 16474 UNSPILL_TMP1(%eax) 16475 ret 16476#endif 16477 16478/* 16479 * After returning from a "selfd" function, pull out the updated values 16480 * and start executing at the next instruction. 16481 */ 16482common_resumeAfterGlueCall: 16483 movl rSELF, %eax 16484 movl offThread_pc(%eax),rPC 16485 movl offThread_curFrame(%eax),rFP 16486 movl offThread_curHandlerTable(%eax),rIBASE 16487 FETCH_INST 16488 GOTO_NEXT 16489 16490/* 16491 * Integer divide or mod by zero 16492 */ 16493common_errDivideByZero: 16494 EXPORT_PC 16495 movl $.LstrDivideByZero,%eax 16496 movl %eax,OUT_ARG0(%esp) 16497 call dvmThrowArithmeticException 16498 jmp common_exceptionThrown 16499 16500/* 16501 * Attempt to allocate an array with a negative size. 16502 * On entry, len in eax 16503 */ 16504common_errNegativeArraySize: 16505 EXPORT_PC 16506 movl %eax,OUT_ARG0(%esp) # arg0<- len 16507 call dvmThrowNegativeArraySizeException # (len) 16508 jmp common_exceptionThrown 16509 16510/* 16511 * Attempt to allocate an array with a negative size. 16512 * On entry, method name in eax 16513 */ 16514common_errNoSuchMethod: 16515 EXPORT_PC 16516 movl %eax,OUT_ARG0(%esp) 16517 call dvmThrowNoSuchMethodError 16518 jmp common_exceptionThrown 16519 16520/* 16521 * Hit a null object when we weren't expecting one. Export the PC, throw a 16522 * NullPointerException and goto the exception processing code. 16523 */ 16524common_errNullObject: 16525 EXPORT_PC 16526 xorl %eax,%eax 16527 movl %eax,OUT_ARG0(%esp) 16528 call dvmThrowNullPointerException 16529 jmp common_exceptionThrown 16530 16531/* 16532 * Array index exceeds max. 16533 * On entry: 16534 * eax <- array object 16535 * ecx <- index 16536 */ 16537common_errArrayIndex: 16538 EXPORT_PC 16539 movl offArrayObject_length(%eax), %eax 16540 movl %eax,OUT_ARG0(%esp) 16541 movl %ecx,OUT_ARG1(%esp) 16542 call dvmThrowArrayIndexOutOfBoundsException # args (length, index) 16543 jmp common_exceptionThrown 16544 16545/* 16546 * Somebody has thrown an exception. Handle it. 16547 * 16548 * If the exception processing code returns to us (instead of falling 16549 * out of the interpreter), continue with whatever the next instruction 16550 * now happens to be. 16551 * 16552 * NOTE: special subMode handling done in dvmMterp_exceptionThrown 16553 * 16554 * This does not return. 16555 */ 16556common_exceptionThrown: 16557.LexceptionNew: 16558 16559 EXPORT_PC 16560 movl rSELF, %ecx 16561 movl %ecx, OUT_ARG0(%esp) 16562 call dvmCheckSuspendPending 16563 16564 movl rSELF, %ecx 16565 movl offThread_exception(%ecx), %edx # %edx <- self->exception 16566 movl %edx, OUT_ARG0(%esp) 16567 movl %ecx, OUT_ARG1(%esp) 16568 SPILL_TMP1(%edx) 16569 call dvmAddTrackedAlloc # don't let the exception be GCed 16570 UNSPILL_TMP1(%edx) 16571 movl rSELF, %ecx 16572 movl offThread_subMode(%ecx), %eax # get subMode flags 16573 movl $0, offThread_exception(%ecx) 16574 16575 # Special subMode? 16576 cmpl $0, %eax # any special subMode handling needed? 16577 je 8f # go if so 16578 16579 # Manage debugger bookkeeping 16580 movl rPC, offThread_pc(%ecx) # update interpSave.pc 16581 movl rFP, offThread_curFrame(%ecx) # update interpSave.curFrame 16582 movl %ecx, OUT_ARG0(%esp) 16583 movl %edx, OUT_ARG1(%esp) 16584 SPILL_TMP1(%edx) 16585 call dvmReportExceptionThrow # (self, exception) 16586 UNSPILL_TMP1(%edx) 16587 movl rSELF, %ecx 16588 165898: 16590 /* 16591 * set up args and a local for &fp 16592 */ 16593 lea 20(%esp), %esp # raise %esp 16594 movl rFP, (%esp) # save fp 16595 movl %esp, %eax # %eax = &fp 16596 lea -20(%esp), %esp # reset %esp 16597 movl %eax, OUT_ARG4(%esp) # Arg 4 = &fp 16598 movl $0, OUT_ARG3(%esp) # Arg 3 = false 16599 movl %edx, OUT_ARG2(%esp) # Arg 2 = exception 16600 movl %ecx, OUT_ARG0(%esp) # Arg 0 = self 16601 16602 movl offThread_method(%ecx), %eax # %eax = self->method 16603 movl offMethod_insns(%eax), %eax # %eax = self->method->insn 16604 movl rPC, %ecx 16605 subl %eax, %ecx # %ecx = pc - self->method->insn 16606 sar $1, %ecx # adjust %ecx for code offset 16607 movl %ecx, OUT_ARG1(%esp) # Arg 1 = %ecx 16608 16609 /* call, %eax gets catchRelPc (a code-unit offset) */ 16610 SPILL_TMP1(%edx) # save exception 16611 call dvmFindCatchBlock # call(self, relPc, exc, scan?, &fp) 16612 UNSPILL_TMP1(%edx) # restore exception 16613 16614 /* fix earlier stack overflow if necessary; may trash rFP */ 16615 movl rSELF, %ecx 16616 cmpl $0, offThread_stackOverflowed(%ecx) # did we overflow? 16617 je 1f # no, skip ahead 16618 movl %eax, rFP # save relPc result in rFP 16619 movl %ecx, OUT_ARG0(%esp) # Arg 0 = self 16620 movl %edx, OUT_ARG1(%esp) # Arg 1 = exception 16621 SPILL_TMP1(%edx) 16622 call dvmCleanupStackOverflow # call(self, exception) 16623 UNSPILL_TMP1(%edx) 16624 movl rFP, %eax # restore result 16625 movl rSELF, %ecx 166261: 16627 16628 /* update frame pointer and check result from dvmFindCatchBlock */ 16629 movl 20(%esp), rFP # retrieve the updated rFP 16630 cmpl $0, %eax # is catchRelPc < 0? 16631 jl .LnotCaughtLocally 16632 16633 /* adjust locals to match self->interpSave.curFrame and updated PC */ 16634 SAVEAREA_FROM_FP rINST # rINST<- new save area 16635 movl offStackSaveArea_method(rINST), rINST # rINST<- new method 16636 movl rINST, offThread_method(%ecx) # self->method = new method 16637 movl offMethod_clazz(rINST), %ecx # %ecx = method->clazz 16638 movl offMethod_insns(rINST), rINST # rINST = method->insn 16639 movl offClassObject_pDvmDex(%ecx), %ecx # %ecx = method->clazz->pDvmDex 16640 lea (rINST, %eax, 2), rPC # rPC<- method->insns + catchRelPc 16641 movl rSELF, rINST 16642 movl %ecx, offThread_methodClassDex(rINST) # self->pDvmDex = method->clazz->pDvmDex 16643 16644 /* release the tracked alloc on the exception */ 16645 movl %edx, OUT_ARG0(%esp) # Arg 0 = exception 16646 movl rINST, OUT_ARG1(%esp) # Arg 1 = self 16647 SPILL_TMP1(%edx) 16648 call dvmReleaseTrackedAlloc # release the exception 16649 UNSPILL_TMP1(%edx) 16650 16651 /* restore the exception if the handler wants it */ 16652 movl rSELF, %ecx 16653 FETCH_INST 16654 movzbl rINSTbl, %eax 16655 cmpl $OP_MOVE_EXCEPTION, %eax # is it "move-exception"? 16656 jne 1f 16657 movl %edx, offThread_exception(%ecx) # restore exception 166581: 16659 movl offThread_curHandlerTable(%ecx), rIBASE # refresh rIBASE 16660 GOTO_NEXT 16661 16662.LnotCaughtLocally: # %edx = exception 16663 /* fix stack overflow if necessary */ 16664 movl rSELF, %ecx 16665 movl offThread_stackOverflowed(%ecx), %eax 16666 cmpl $0, %eax # did we overflow earlier? 16667 je 1f 16668 movl %ecx, OUT_ARG0(%esp) 16669 movl %edx, OUT_ARG1(%esp) 16670 SPILL_TMP1(%edx) 16671 call dvmCleanupStackOverflow 16672 UNSPILL_TMP1(%edx) 16673 166741: 16675 movl rSELF, %ecx 16676 movl %edx, offThread_exception(%ecx) #restore exception 16677 movl %edx, OUT_ARG0(%esp) 16678 movl %ecx, OUT_ARG1(%esp) 16679 call dvmReleaseTrackedAlloc # release the exception 16680 movl rSELF, %ecx 16681 jmp common_gotoBail # bail out 16682 16683common_abort: 16684 movl $0xdeadf00d,%eax 16685 call *%eax 16686 16687 16688/* 16689 * Strings 16690 */ 16691 16692 .section .rodata 16693.LstrDivideByZero: 16694 .asciz "divide by zero" 16695.LstrFilledNewArrayNotImplA: 16696 .asciz "filled-new-array only implemented for 'int'" 16697 16698