/* Copyright (C) 2008 The Android Open Source Project
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */

   /*
    * File: OP_IGET_WIDE.S
    *
    * Code: 64 bit instance field "get" operation. Uses no substitutions.
    *
    * For: iget-wide
    *
    * Description: Perform the object instance field "get" operation
    *              with the identified field; load the instance value into
    *              the value register.
    *
    * Format:  B|A|op CCCC (22c)
    *
    * Syntax: op vA, vB, type@CCCC
    *         op vA, vB, field@CCCC
    */

    movl        rGLUE, %eax             # %eax<- MterpGlue pointer
    movl        offGlue_methodClassDex(%eax), %ecx # %ecx<- pDvmDex
    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- CCCC
    FETCH       1, %edx                 # %edx<- pDvmDex->pResFields
    movl        (%ecx, %edx, 4), %ecx   # %ecx<- resolved InstField ptr
    cmp         $$0, %ecx               # check for null ptr; resolved InstField ptr
    jne         .L${opcode}_finish
    movl        offGlue_method(%eax), %ecx # %ecx <- current method
    EXPORT_PC                           # in case an exception is thrown
    movl        offMethod_clazz(%ecx), %ecx # %ecx<- method->clazz
    movl        %ecx, -8(%esp)          # push parameter CCCC; field ref
    movl        %edx, -4(%esp)          # push parameter method->clazz
    jmp         .L${opcode}_finish2
%break

.L${opcode}_finish2:
    lea         -8(%esp), %esp
    call        dvmResolveInstField     # resolve InstField ptr
                                        # call: (const ClassObject* referrer, u4 ifieldIdx)
                                        # return: InstField*
    cmp         $$0, %eax               # check if resolved
    lea         8(%esp), %esp
    movl        %eax, %ecx              # %ecx<- %eax; %ecx expected to hold field
    je          common_exceptionThrown

   /*
    *  %ecx holds resolved field
    */

.L${opcode}_finish:

    movl        rINST, %edx             # %edx<- BA
    shr         $$4, %edx               # %edx<- B
    andl        $$15, rINST             # rINST<- A
    GET_VREG    %edx                    # %edx<- vB
    cmp         $$0, %edx               # check for null object
    je          common_errNullObject
    movl        offInstField_byteOffset(%ecx), %ecx # %ecx<- field offset
    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
    movq        (%ecx, %edx), %xmm0     # %xmm0<- object field
    movq        %xmm0, (rFP, rINST, 4)  # vA<- %xmm0; object field
    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp