Home | History | Annotate | Download | only in x86
      1 %verify "executed"
      2 %verify "exception handled"
      3     /*
      4      * Execute a "native inline" instruction.
      5      *
      6      * We will be calling through a function table:
      7      *
      8      * (*gDvmInlineOpsTable[opIndex].func)(arg0, arg1, arg2, arg3, pResult)
      9      *
     10      * Ignores argument count - always loads 4.
     11      *
     12      */
     13     /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
     14     movl      rSELF,%ecx
     15     EXPORT_PC
     16     movzwl    2(rPC),%eax               # eax<- BBBB
     17     SPILL(rIBASE)                       # preserve rIBASE
     18     movl      offThread_subMode(%ecx), %edx # edx<- submode flags
     19     andl      $$kSubModeDebugProfile, %edx # debug or profile mode active?
     20     jnz       .L${opcode}_debugprofile   # yes, take slow path
     21 .L${opcode}_resume:
     22     leal      offThread_retval(%ecx),%ecx # ecx<- &self->retval
     23     movl      %ecx,OUT_ARG4(%esp)
     24     call      .L${opcode}_continue      # make call; will return after
     25     UNSPILL(rIBASE)                     # restore rIBASE
     26     testl     %eax,%eax                 # successful?
     27     jz        common_exceptionThrown    # no, handle exception
     28     FETCH_INST_OPCODE 3 %ecx
     29     ADVANCE_PC 3
     30     GOTO_NEXT_R %ecx
     31 
     32 .L${opcode}_continue:
     33     /*
     34      * Extract args, call function.
     35      *  ecx = #of args (0-4)
     36      *  eax = call index
     37      *  @esp = return addr
     38      *  esp is -4 from normal
     39      *
     40      *  Go ahead and load all 4 args, even if not used.
     41      */
     42     movzwl    4(rPC),rIBASE
     43 
     44     movl      $$0xf,%ecx
     45     andl      rIBASE,%ecx
     46     GET_VREG_R  %ecx %ecx
     47     sarl      $$4,rIBASE
     48     movl      %ecx,4+OUT_ARG0(%esp)
     49 
     50     movl      $$0xf,%ecx
     51     andl      rIBASE,%ecx
     52     GET_VREG_R  %ecx %ecx
     53     sarl      $$4,rIBASE
     54     movl      %ecx,4+OUT_ARG1(%esp)
     55 
     56     movl      $$0xf,%ecx
     57     andl      rIBASE,%ecx
     58     GET_VREG_R  %ecx %ecx
     59     sarl      $$4,rIBASE
     60     movl      %ecx,4+OUT_ARG2(%esp)
     61 
     62     movl      $$0xf,%ecx
     63     andl      rIBASE,%ecx
     64     GET_VREG_R  %ecx %ecx
     65     sarl      $$4,rIBASE
     66     movl      %ecx,4+OUT_ARG3(%esp)
     67 
     68     sall      $$4,%eax      # index *= sizeof(table entry)
     69     jmp       *gDvmInlineOpsTable(%eax)
     70     # will return to caller of .L${opcode}_continue
     71 
     72     /*
     73      * We're debugging or profiling.
     74      * eax: opIndex
     75      */
     76 .L${opcode}_debugprofile:
     77     movl      %eax,OUT_ARG0(%esp)       # arg0<- BBBB
     78     SPILL_TMP1(%eax)                    # save opIndex
     79     call      dvmResolveInlineNative    # dvmResolveInlineNative(opIndex)
     80     movl      rSELF,%ecx                # restore self
     81     testl     %eax,%eax                 # method resolved?
     82     movl      %eax,%edx                 # save possibly resolved method in edx
     83     UNSPILL_TMP1(%eax)                  # in case not resolved, restore opIndex
     84     jz        .L${opcode}_resume        # not resolved, just move on
     85     SPILL_TMP2(%edx)                    # save method
     86     movl      %edx,OUT_ARG0(%esp)       # arg0<- method
     87     movl      %ecx,OUT_ARG1(%esp)       # arg1<- self
     88     call      dvmFastMethodTraceEnter   # dvmFastMethodTraceEnter(method,self)
     89     movl      rSELF,%ecx                # restore self
     90     UNSPILL_TMP1(%eax)                  # restore opIndex
     91     leal      offThread_retval(%ecx),%ecx # ecx<- &self->retval
     92     movl      %ecx,OUT_ARG4(%esp)       # needed for pResult of inline operation handler
     93     call      .L${opcode}_continue      # make call; will return after
     94     SPILL_TMP1(%eax)                    # save result of inline
     95     UNSPILL_TMP2(%eax)                  # restore method
     96     movl      rSELF,%ecx                # restore self
     97     movl      %eax,OUT_ARG0(%esp)       # arg0<- method
     98     movl      %ecx,OUT_ARG1(%esp)       # arg1<- self
     99     call      dvmFastNativeMethodTraceExit # dvmFastNativeMethodTraceExit(method,self)
    100     UNSPILL(rIBASE)                     # restore rIBASE
    101     UNSPILL_TMP1(%eax)                  # restore result of inline
    102     testl     %eax,%eax                 # successful?
    103     jz        common_exceptionThrown    # no, handle exception
    104     FETCH_INST_OPCODE 3 %ecx
    105     ADVANCE_PC 3
    106     GOTO_NEXT_R %ecx
    107